验证码输入组件 Verify Account UI
1. 概述
项目本体展示了一个验证码输入组件.
涉及的知识点:
- 使用
.code::-webkit-outer-spin-button, .code::-webkit-inner-spin-button
清除Safari
默认的输入框内容调整上下键 - 使用
caret-color: transparent;
控制输入框光标的颜色
效果:
2. 结构和切图
网页的基本结构如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<div class="container">
<h2>Verify Your Account</h2>
<p>We emailed you the six digit code to esuadmin@esu.moe <br/> Enter the credential below to confirm your email address.</p>
<div class="code-container">
<input type="number" class="code" placeholder="0" min="0" max="9" required>
<input type="number" class="code" placeholder="0" min="0" max="9" required>
<input type="number" class="code" placeholder="0" min="0" max="9" required>
<input type="number" class="code" placeholder="0" min="0" max="9" required>
<input type="number" class="code" placeholder="0" min="0" max="9" required>
<input type="number" class="code" placeholder="0" min="0" max="9" required>
</div>
<small class="info">
This is design only. we won't be able to send you an email as we don't really have your email, right?
</small>
</div>
</body>
3. 编写 CSS
样式
首先将 body
排版方式设为水平垂直居中:
1
2
3
4
5
6
7
8
9
10
body {
background-color: #fbfcfe;
font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}
然后设定最大的容器 container
和只包含单个数码的容器 code-container
的样式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.container {
background-color: #fff;
border: 3px #000 solid;
border-radius: 10px;
padding: 30px;
max-width: 1000px;
text-align: center;
}
.code-container {
display: flex;
align-items: center;
justify-content: center;
margin: 40px 0;
}
再设定容器中用于输入数码的输入框样式. 注意此处对默认样式的清除方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.code {
caret-color: transparent;
border-radius: 5px;
font-size: 75px;
height: 120px;
width: 100px;
border: 1px solid #eee;
margin:1%;
text-align: center;
font-weight: 300;
-moz-appearance: textfield;
}
.code::-webkit-outer-spin-button,
.code::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
在监测到输入合法内容 ($0 ~ 9$) 后, 将对应的输入框边框颜色调为蓝色:
1
2
3
4
.code:valid {
border-color: #3498db;
box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.25);
}
最后调整信息提示框的背景, 边框弧度和响应式布局规则:
1
2
3
4
5
6
7
8
9
10
11
@media (max-width: 600px) {
.code-container {
flex-wrap: wrap;
}
.code {
font-size: 60px;
height: 80px;
max-width: 70px;
}
}
完整的 CSS
样式表如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
* {
box-sizing: border-box;
}
body {
background-color: #fbfcfe;
font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
overflow: hidden;
margin: 0;
}
.container {
background-color: #fff;
border: 3px #000 solid;
border-radius: 10px;
padding: 30px;
max-width: 1000px;
text-align: center;
}
.code-container {
display: flex;
align-items: center;
justify-content: center;
margin: 40px 0;
}
.code {
caret-color: transparent;
border-radius: 5px;
font-size: 75px;
height: 120px;
width: 100px;
border: 1px solid #eee;
margin:1%;
text-align: center;
font-weight: 300;
-moz-appearance: textfield;
}
.code::-webkit-outer-spin-button,
.code::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.code:valid {
border-color: #3498db;
box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.25);
}
.info {
background-color: #eaeaea;
display: inline-block;
line-height: 20px;
max-width: 400px;
color: #777;
border-radius: 5px;
}
@media (max-width: 600px) {
.code-container {
flex-wrap: wrap;
}
.code {
font-size: 60px;
height: 80px;
max-width: 70px;
}
4. JavaScript
最后, 我们编写 JavaScript
函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// select all digits
const codes = document.querySelectorAll('.code')
// focus on the 1st digit
codes[0].focus()
codes.forEach((code, idx) => {
code.addEventListener('keydown', (e) => {
// case: valid input
if(e.key >= 0 && e.key <=9) {
// then should assign 'e.value'...why assign the value null?
codes[idx].value = ''
// then move the active cursor to the next one
setTimeout(() => codes[idx + 1].focus(), 10)
} else if(e.key === 'Backspace') {
// then move the active cursor back
setTimeout(() => codes[idx - 1].focus(), 10)
}
})
})
最后, 完整的网页演示可见 此处