如何在没有 JavaScript 的情况下创建 4 位输入序列?
How to create a 4 digit input series without JavaScript?
我有一个表格输入,我想在其中输入一个四位数字(验证码)。我的问题是,在输入第四个数字后,PIN 码的结构和顺序发生了故障。因为当我定义了四个字符时,文本指针指向第五个字符。
有没有办法用纯CSS解决这个问题?或者至少用纯 JavaScript?
.pinBox {
display: inline-block;
overflow: hidden;
position: relative;
direction: ltr;
text-align: left;
}
.pinBox:before {
position: absolute;
left: 0;
right: 0;
content: '';
pointer-events: none;
display: block;
height: 75px;
width: 300px;
background-image: url(https://i.stack.imgur.com/JbkZl.png);
}
.pinEntry {
position: relative;
padding: 16px 29px;
font-family: courier, monospaced;
font-size: xx-large;
border: none;
outline: none;
width: 302px;
letter-spacing: 55px;
background-color: transparent;
overflow: hidden;
text-align: left;
direction: ltr;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.1/css/bootstrap.css"/>
<form role="form" method="POST" action="">
<div class="row my-4">
<div class="col-12 text-center">
<div class="pinBox">
<input class="pinEntry" name="token" type="text" maxlength="4" value="">
</div>
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary mt-2">submit</button>
</div>
</form>
这是一个jsfidde demo
经过一番调查后,我意识到奇怪的是,通过将 overflow: hidden;
分配给父元素,一旦插入第 4 个值,就会导致输入到 hop/move 上下文 X 位置。
解决方案:
- 在
<input>
元素上使用 CSS clip
!
- 将方形网格指定为父元素的
background-image
(无需使用 ::before
伪元素!)
.pinBox {
--width: 296px;
--height: 74px;
--spacing: 47px;
display: inline-block;
position: relative;
width: var(--width);
height: var(--height);
background-image: url(https://i.stack.imgur.com/JbkZl.png);
}
.pinEntry {
position: absolute;
padding-left: 21px;
font-family: courier, monospaced;
font-size: var(--spacing);
height: var(--height);
letter-spacing: var(--spacing);
background-color: transparent;
border: 0;
outline: none;
clip: rect(0px, calc(var(--width) - 21px), var(--height), 0px);
}
<div class="pinBox">
<input class="pinEntry" name="token" type=text maxlength=4 autocomplete=off >
</div>
上面的一个缺点是:一旦输入了所有四个值,并且如果用户单击在第四个值 之后 - 插入符号将不可见,因为它被 clipped (letter-spaced 在第 5 个位置内)。你可以忍受它 - 很好,但在我看来它很糟糕 UX/UI。
也许你可以在上面添加一些非常小的 JS:
- 如果输入有 4 个值长度 - select 所有 text-value 使用
myInput.select()
示例:
const ELS_pinEntry = document.querySelectorAll(".pinEntry");
const selectAllIfFull = (evt) => {
const EL_input = evt.currentTarget;
if (EL_input.value.length >= 4) EL_input.select();
};
ELS_pinEntry.forEach(el => {
el.addEventListener("focusin", selectAllIfFull);
});
.pinBox {
--width: 296px;
--height: 74px;
--spacing: 47px;
display: inline-block;
position: relative;
width: var(--width);
height: var(--height);
background-image: url(https://i.stack.imgur.com/JbkZl.png);
}
.pinEntry {
position: absolute;
padding-left: 21px;
font-family: courier, monospaced;
font-size: var(--spacing);
height: var(--height);
letter-spacing: var(--spacing);
background-color: transparent;
border: 0;
outline: none;
clip: rect(0px, calc(var(--width) - 21px), var(--height), 0px);
}
<div class="pinBox">
<input class="pinEntry" name="token" type=text maxlength=4 autocomplete=off >
</div>
另一个 cons 我会通过使用上面的(和原来的)想法来改进:A11Y (Accessibility).
许多视力不好或有问题的用户在浏览网站时应该能够看到输入 outline
。出于设计原因,上面必须删除 INPUT 元素上的 CSS outline
。这是一个 no-no.
目前我没有其他 better/simpler 想法,只能使用 4 个不同的输入 并将它们的值连接到一个隐藏的最终将与 FORM 一起提交。
我有一个表格输入,我想在其中输入一个四位数字(验证码)。我的问题是,在输入第四个数字后,PIN 码的结构和顺序发生了故障。因为当我定义了四个字符时,文本指针指向第五个字符。
有没有办法用纯CSS解决这个问题?或者至少用纯 JavaScript?
.pinBox {
display: inline-block;
overflow: hidden;
position: relative;
direction: ltr;
text-align: left;
}
.pinBox:before {
position: absolute;
left: 0;
right: 0;
content: '';
pointer-events: none;
display: block;
height: 75px;
width: 300px;
background-image: url(https://i.stack.imgur.com/JbkZl.png);
}
.pinEntry {
position: relative;
padding: 16px 29px;
font-family: courier, monospaced;
font-size: xx-large;
border: none;
outline: none;
width: 302px;
letter-spacing: 55px;
background-color: transparent;
overflow: hidden;
text-align: left;
direction: ltr;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.1/css/bootstrap.css"/>
<form role="form" method="POST" action="">
<div class="row my-4">
<div class="col-12 text-center">
<div class="pinBox">
<input class="pinEntry" name="token" type="text" maxlength="4" value="">
</div>
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary mt-2">submit</button>
</div>
</form>
这是一个jsfidde demo
经过一番调查后,我意识到奇怪的是,通过将 overflow: hidden;
分配给父元素,一旦插入第 4 个值,就会导致输入到 hop/move 上下文 X 位置。
解决方案:
- 在
<input>
元素上使用 CSSclip
! - 将方形网格指定为父元素的
background-image
(无需使用::before
伪元素!)
.pinBox {
--width: 296px;
--height: 74px;
--spacing: 47px;
display: inline-block;
position: relative;
width: var(--width);
height: var(--height);
background-image: url(https://i.stack.imgur.com/JbkZl.png);
}
.pinEntry {
position: absolute;
padding-left: 21px;
font-family: courier, monospaced;
font-size: var(--spacing);
height: var(--height);
letter-spacing: var(--spacing);
background-color: transparent;
border: 0;
outline: none;
clip: rect(0px, calc(var(--width) - 21px), var(--height), 0px);
}
<div class="pinBox">
<input class="pinEntry" name="token" type=text maxlength=4 autocomplete=off >
</div>
上面的一个缺点是:一旦输入了所有四个值,并且如果用户单击在第四个值 之后 - 插入符号将不可见,因为它被 clipped (letter-spaced 在第 5 个位置内)。你可以忍受它 - 很好,但在我看来它很糟糕 UX/UI。
也许你可以在上面添加一些非常小的 JS:
- 如果输入有 4 个值长度 - select 所有 text-value 使用
myInput.select()
示例:
const ELS_pinEntry = document.querySelectorAll(".pinEntry");
const selectAllIfFull = (evt) => {
const EL_input = evt.currentTarget;
if (EL_input.value.length >= 4) EL_input.select();
};
ELS_pinEntry.forEach(el => {
el.addEventListener("focusin", selectAllIfFull);
});
.pinBox {
--width: 296px;
--height: 74px;
--spacing: 47px;
display: inline-block;
position: relative;
width: var(--width);
height: var(--height);
background-image: url(https://i.stack.imgur.com/JbkZl.png);
}
.pinEntry {
position: absolute;
padding-left: 21px;
font-family: courier, monospaced;
font-size: var(--spacing);
height: var(--height);
letter-spacing: var(--spacing);
background-color: transparent;
border: 0;
outline: none;
clip: rect(0px, calc(var(--width) - 21px), var(--height), 0px);
}
<div class="pinBox">
<input class="pinEntry" name="token" type=text maxlength=4 autocomplete=off >
</div>
另一个 cons 我会通过使用上面的(和原来的)想法来改进:A11Y (Accessibility).
许多视力不好或有问题的用户在浏览网站时应该能够看到输入 outline
。出于设计原因,上面必须删除 INPUT 元素上的 CSS outline
。这是一个 no-no.
目前我没有其他 better/simpler 想法,只能使用 4 个不同的输入 并将它们的值连接到一个隐藏的最终将与 FORM 一起提交。