前端切图学习-验证码输入组件

verify-account-ui

Posted by R1NG on August 31, 2021 Viewed Times

验证码输入组件 Verify Account UI

1. 概述

项目本体展示了一个验证码输入组件.

涉及的知识点:

  1. 使用 .code::-webkit-outer-spin-button, .code::-webkit-inner-spin-button 清除 Safari 默认的输入框内容调整上下键
  2. 使用 caret-color: transparent; 控制输入框光标的颜色

效果:

20210901213120


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)
        }
    })
})

最后, 完整的网页演示可见 此处