表单在移动设备上常常让人头疼。 我们可以通过对上下文做出反应,尽可能地使流程变得流畅。 期待数字值的输入字段应该具有数字UI。 在小屏幕上调出数字键盘在大多数平台上都很容易——只需使用<input type="number">
。

这个大按钮数字键盘对手指友好,有助于防止用户因沮丧而放弃您的表单。 但是,type="number"
并不适用于所有数字。
在(大多数)较大的屏幕上,数字输入带有增量/减量按钮。 这是我们默认情况下免费获得的一个有用的UI元素。 但是,它确实使这种类型的输入对于信用卡号等完全不合适。

该规范本身就明确说明了这一点。
type=number
状态不适用于碰巧仅由数字组成但严格来说不是数字的输入。 例如,它不适用于信用卡号或美国邮政编码。 确定是否使用type=number
的一种简单方法是考虑输入控件是否有意义地使用微调框界面(例如,带有“向上”和“向下”箭头)。 信用卡号的最后一位数字出错1位并非小错,它与所有数字都错误一样严重。 因此,用户不应使用“向上”和“向下”按钮来选择信用卡号。 当微调框界面不合适时,type=text
可能是正确的选择(可能带有pattern
属性)。
使用CSS隐藏向上和向下按钮很容易
input[type="number"] {
-moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
需要注意的是,这并不是数字输入和文本输入之间唯一的区别。您绝对应该遵循此方面的规范! 一些旧版浏览器会为数字输入删除前导零,这对美国邮政编码来说将是一个大问题。 通常有用的maxlength
属性在数字输入上被忽略。
是的,是的,是的!<input type=number>终于可以迎来它应得的烈火焚身了!
—— Monica Dinculescu (@notwaldorf) 2018年3月13日
为什么有人会不喜欢这样一个有用的输入?
答案归结为验证和将输入用于错误的事情。数字输入默认执行输入清理。 如果用户输入任何不是有效数字的内容,该值将等于空字符串——无论用户在屏幕上看到什么。
这种输入清理可能会让开发者感到困惑,而且无法关闭。 如果您希望允许输入不是有效数字的内容,请勿使用type="number"
。

var numberinput = document.querySelector('input[type="number"]')
numberinput.value // will be ""
这可能不是您直觉上期望的结果。 但是,如果您遵循规范,并且仅将数字输入用于其设计目的——实际数字——此行为则不会有问题。
数字输入替代方案
iOS解决方案:在文本输入上使用`pattern`属性
在iOS设备上,使用值为[0-9]*
的pattern
属性将调出数字键盘。 这仅适用于此确切的模式——您不能允许任何额外的字符。
<label for="creditcard">credit card number:</label> <input pattern="[0-9]*" type="text" name="creditcard">

pattern
属性的iOS请记住,当显示此键盘时,iPhone不会允许用户切换键盘类型。确保这些是他们正确填写输入所需的唯一键。
如果要在iOS上调出大型数字键的键盘,则需要在数字输入上使用pattern
属性。 否则,您将获得小巧且对手指友好的按钮

<input type="number">
的iOS键盘更好的解决方案:`inputmode`
inputmode
已经成为WHATWG规范几年了,并且从Chrome 66版本开始最终得到了实现
此浏览器支持数据来自Caniuse,其中包含更多详细信息。 数字表示浏览器在该版本及更高版本中支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
66 | 95 | 否 | 79 | 否 |
移动/平板电脑
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 12.2-12.5 |
为了获得尽可能广泛的支持,可以将其与pattern
属性结合使用以用于iOS
<label for="creditcard">credit card number:</label> <input inputmode="numeric" pattern="[0-9]*" type="text" name="creditcard">
这使开发人员能够完全控制移动UI,而没有任何额外负担。 它使UI对手指友好,同时又比pattern
属性更通用,因为我们可以允许任何我们喜欢的字符。 它控制一件事情——并且只有一件事。 inputmode
是当使用type="number"
不合适时的一个很好的解决方案。
有些人会更进一步,一旦inputmode
获得更好的支持,就会完全放弃type="number"
。 我不确定这是否明智,但type="number"
可能会存在问题。
if (numberInput.validity.valueMissing) {
errorMessage.textContent = "field must not be empty"
}

如果您想明确警告空数字输入,则需要使用
if (numberInput.validity.valueMissing && !numberInput.validity.badInput) {
errorMessage.textContent = "field must not be empty"
}
根据Google的说法,与台式机相比,用户在移动设备上放弃购买的频率是其两倍。 手机上的销售额仅占所有完成的在线购买的三分之一。 显然,人们无法容忍笨拙地浏览设计糟糕的表单并在微小的输入上戳戳点点。 数据输入需要毫不费力。 虽然浏览器支持目前较低,但我们实际上只是在等待移动浏览器。 桌面支持在很大程度上无关紧要。 HTML5引入的输入元素很棒,但它们错过了一些极端情况。 这可以填补一些空白。
感谢这篇文章! 我的团队最近遇到了使用
number
字段的这个确切陷阱,当我们发现另一个非常棘手的跨浏览器问题时:逗号。 一些浏览器认为逗号是数字,一些浏览器根本不允许输入逗号,无论如何,在输入的.value
属性被清除之前,都不可能使用JS验证它们。以下是我为
<input type="number">
创建的一个小型跨浏览器测试练习,以防它对任何人有所帮助:https://codepen.io/adamnorwood/pen/aqJZZb?editors=1000不错的文章! 我很好奇HTML的未来以及如何改善移动输入UX。 我最近做了一些挖掘,发现了一个关于如何在移动设备上尽可能好地进行数据输入的不错的备忘单。 令我震惊的是,有多少网站在这方面做错了。 https://baymard.com/labs/touch-keyboard-types
我一直在使用input type = tel,它接受模式参数并在移动设备上调出数字键盘输入。
同意,我检查了规范,看起来它的验证方式与文本输入相同,所以我觉得这是目前最接近的最佳解决方案。
移动设备上type=”tel”的键盘有一些特定于手机的字符,如#,但它是一个不错的解决方案,直到inputmode的支持更好,即使它在语义上感觉不正确。 它似乎不会以负面方式影响屏幕阅读器。
感谢您的文章!
您如何看待input type=”phone”?
尚未检查最新的最佳实践,但我一直在使用“tel”输入作为数字输入的替代品。