规范故意没有说明实现(浏览器)如何处理 UI。在本文中,我们专门研究 <input type="number">
,您可能会惊讶地发现规范 明确说明
此规范未定义用户代理应使用哪些用户界面。
它接着解释说,不同的语言、文化和地区可能具有合理的理由以不同的方式处理数字输入。因此,浏览器在这方面是独立的,也许不出所料,对于 UI 存在许多不同的方法。让我们来看一看。
标记
<form>
<label for="age">Enter your age</label>
<input type="number" id="age" name="age">
</form>
这将生成一个简单的表单,其中包含一个接受数字值的输入。我在接下来的演示中添加了一些用于演示目的的 CSS,但这是我们正在查看的基本 HTML 标记。
Internet Explorer 如何处理它

Internet Explorer 在桌面浏览器中提供了最简单的默认演示。输入看起来像任何其他接受文本的表单输入。实际上,IE 根本没有为我们做出任何用户界面决策,只是在输入了一些内容后能够清除输入。这是一个方便的小功能,其他浏览器没有包含(尽管它有时出现在 type="search"
输入中)。
Firefox 如何处理它

Firefox 引入了 IE 中没有的 UI:微调器控件。这些控件包括向上和向下箭头,分别在点击时增加和减少字段的数字值。
使用 appearance
属性,可以通过一些 CSS 代码去除这些控件。
/* Remove controls from Firefox */
input[type=number] {
-moz-appearance: textfield;
}
虽然这很好地去除了控件,但我们似乎无法控制它们的设计。
Safari 如何处理它

Firefox 和 Safari 在处理数字输入的方式上很相似。两者都包含微调器控件,并且两者都没有包含在 IE 中看到的清除 UI。
我们也可以从 Safari 中去除控件,但与 Firefox 不同,我们使用一种针对 Shadow DOM 的方法。
/* Remove controls from Safari and Chrome */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0; /* Removes leftover margin */
}
我们可以使用 Shadow DOM 样式化的另一个元素是围绕数字的不可见框。
/* Adds a box around the numeric value in Safari and Chrome */
input[type=number]::-webkit-textfield-decoration-container {
border: 1px #ccc solid;
background: #efefef;
}
可能有用,也可能没用。无论哪种方式,与我们迄今为止所看到的相比,Safari(和 Chrome)中具有更大的设计灵活性,这很好。
Chrome 如何处理它

Chrome 处于人群中的中间位置。乍一看,我们看到的是一个简单的表单输入。然后,当光标移到该字段上时,会显示 Firefox 和 Safari 中相同的控件。
同样,有趣的是,Firefox、Safari、Chrome 和 Opera 认为数量控件对用户体验有足够的益处,因此在 IE 没有包含它们的地方包含了它们。另一方面,Chrome 通过在悬停时显示控件而不是默认显示它们,处于中间立场。
如果我们希望 Firefox 像 Chrome 一样在悬停时显示控件?我们可以像之前一样从 Firefox 中去除控件,然后在 :hover
和 :focus
上重新应用它们。
/* Remove controls from Firefox */
input[type=number] {
-moz-appearance: textfield;
}
/* Re-applies the controls on :hover and :focus */
input[type="number"]:hover,
input[type="number"]:focus {
-moz-appearance: number-input;
}
虽然 Chrome 和 Safari 可能不像我们预期的那样相似,但它们确实共享使用 Shadow DOM 元素来样式化和操作输入的能力。实际上,Safari 部分中介绍的相同技术也适用于 Chrome。
Opera 如何处理它
Opera 处理数字输入的方式与 Chrome 完全相同。这并不令人惊讶,因为 Opera 采用了与 Chrome 相同的 Blink 渲染引擎。这意味着在 Safari 和 Chrome 中隐藏和样式化输入的相同 CSS 技巧也适用于 Opera。
由于 Opera 最近才更新到 Blink,因此查看其最后一次更新前的版本 Opera 12 如何处理数字输入非常有趣。

这里的区别在于控件如何在输入框外浮动。Firefox、Safari、Chrome 和最新的 Opera 将控件直接放置在输入框内,而 Opera 12 将它们完全放置在字段之外。更值得注意的是 Opera 如何决定在控件周围放置边框。这会创建一个看起来像是包含按钮的完整用户界面,默认情况下会扩展输入框的宽度。
从 Opera 中去除控件并非易事,只能通过将 HTML 中的输入类型更改为 text
并严格将接受的字符模式限制为数字来去除。
<form>
<label for="age">Enter your age</label>
<input type="text" pattern="[0-9]*" id="age" name="age">
</form>
另一个区别是数字是如何右对齐的。这有点让人想起 Excel 如何自动将数字电子表格单元格右对齐。所有其他浏览器都将文本左对齐,因此我们可以使用 CSS 强制 Opera 执行相同的操作。
html:not([dir="rtl"]) input {
text-align: left;
}
此代码片段搜索 DOM 中任何未设置为从右到左的输入,并将文本强制到左侧。如写的那样,这将全局应用,但如果需要,可以修改为更具体。
最后一个值得注意的细节是在 :focus
上发生的全部突出显示。当字段被选中时,Opera 会应用看起来最重的样式,一直到数量控件,这些控件在点击时具有自己的活动状态。
移动版 Safari 和 Android 如何处理它


并排比较时,移动版 Safari 和 Android 浏览器非常相似。两者都像 IE 一样,在输入框上没有直接提供任何控件,但它们也与 IE 不同,因为它们没有为输入框提供额外的用户界面,以便在输入了一些内容后清除输入框。从这个意义上讲,移动浏览器提供了整个集合中最简单的默认实现。
这些浏览器识别 type="number"
,并在输入框处于焦点时立即提供数字键盘。这非常酷,也很好地提醒我们,为任何表单字段添加正确的 type
是获得良好用户体验的良好做法。
结果
以下是本文中所述调查结果的摘要。
它有吗? | IE | Safari | Firefox | Chrome | Opera | iOS | Android |
---|---|---|---|---|---|---|---|
微调器控件 | 否 | 是 | 是 | 悬停时 | 悬停时 | 否 | 否 |
清除控件 | 是 | 否 | 否 | 否 | 否 | 否 | 否 |
左对齐 | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
焦点样式 | 悬停时 | 是 | 是 | 是 | 是 | 否 | 否 |
键盘命令 | 是 | 是 | 是 | 是 | 是 | 否 | 否 |
Shadow DOM 控件 | 否 | 是 | 否 | 是 | 是 | 否 | 否 |
结论
当浏览器表现不同时,这可能会让人感到沮丧。我们很长时间以来一直在以各种方式处理这个问题。这就是发现黑客——不对,技巧——的方式。
这种比较揭示了一个有趣的事情:这些差异如何影响用户体验。如果我们创建一个数字表单输入并依赖浏览器默认设置来处理显示,那么网站的两个不同访问者很可能会拥有两种截然不同的体验。尽管这种体验对于他们来说在*不同*网站上可能是保持一致的,因为用户很可能会坚持使用同一个浏览器。
你对这些 UI 差异有什么想法吗?你是否有一个最喜欢的?你尝试过覆盖它们吗?我们在这里可以使用 JavaScript 做些什么?请在评论中分享你的想法。
让我惊讶的是,我认为 IE 在这里做对了。我真的不喜欢在可以简单地输入东西时使用表单元素。(必须使用下拉菜单填写我地址中的州是我的一块心病。)
Chrome 的实现是最糟糕的。这些控件还能再小一点吗?这对可访问性来说非常糟糕。
在所有提到的浏览器中,你也可以直接输入一个数字。
我想这些截图是在 Mac 上制作的,旋转按钮在那里比我在 Windows 版本的这些浏览器上的要小得多,但在不同的浏览器中更加一致。
非常有趣的内容,感谢分享 :)
@RioBrewster 我 110% 同意。
IE 在这方面做得很好,清除“X”是这种情况所需的一切。数量控件没有必要,它们要求用户做太多工作。
Firefox、Chrome 和 Safari 的数量控件太小了,几乎无法使用,要将指针指向正确的箭头需要花费太多努力。
没有人喜欢上下箭头吗?我确信我喜欢显示它们的原因是,用户可以在不阅读或了解任何上下文的情况下看到预期的输入(我看到了这个论点的缺陷,但我仍然相信它有一些道理)。
我认为没有多少人会觉得被迫实际使用箭头。
给 RioBrewster 的一个提示(虽然我完全同意这可能很烦人):如果你足够快地输入你的州,它将选择正确的选项。
@Rene,
只有当你的州是第一个以该字母开头的州时,输入州名才有效。所以,如果我输入 TX,我会得到 TN。当我住在 CA 的时候,这并不是什么大问题,因为我不必滚动下拉菜单,而且输入“C”会得到 CA。
我想这是 CA 比德克萨斯州少有的优势之一。;^)
我认为这取决于浏览器。有些浏览器允许你输入搜索词(“T”、“X”),它会跳到该项目。其他浏览器,第一个“T”会带你到第一个“T”条目,然后后续的“T”(按顺序)会带你到后续的“T”条目。作为德克萨斯州的居民,我已经习惯了输入“TT”来跳转到我的州条目。至少在 FF 中是这样的。
@RioBrewster,在州下拉菜单中,你也可以继续按 T 来循环遍历其他以 T 开头的州。
我们必须同意不同意。
如果我的数字输入只使用整数,并且 step 属性设置为 1,那么这些控件可能显得多余。当 step 不等于 1 时,这些控件确实有助于传达该特定字段认为有效的条目是什么。
此外,这些控件可以很容易地用 CSS 隐藏,这使我们拥有了两个世界中最好的选择,因此要感谢选项!
关于使用 type=”tel” 来调出纯数字键盘有什么想法吗?它比仅仅使用数字/符号键盘好得多,但我也不想编写糟糕的标记。
我也觉得这样做有点“脏”,但是那些上下控件真的很烦人。
number
的问题是,一个数字可以包含符号,因此你不能真正只显示数字。你必须使用
pattern="\d*"
来指定 0 个或多个数字。这将调出正确的键盘。“pattern” 参数并不总是有效。有一次,我正在开发一个数字字段,用户必须在其中输入一个小数。一些 Android 版本不显示正确的键盘。它显示的是手机键盘,但我想让它显示一个带有小数点(或逗号,在某些语言中)的键盘。即使设备拥有最新的 Android 版本,制造商(如三星)也可以更改默认键盘,并且无法正确实现它。
由于该系统专门针对 Android 用户设计,因此解决方案很奇怪。我必须使用 type=”tel” 和一段 JavaScript 代码,在用户输入 2 位数字后自动添加小数分隔符 http://jquerypriceformat.com/#examples
非常好的比较,但我错过了 Android 的截图。
关于使用上下箭头来增加/减少数字的支持呢?
我的意思是上下键
鼠标滚轮上下在某些浏览器中也有效
Chrome 支持上下箭头和鼠标滚轮。
另一个技巧:如果你这样做
Mobile Safari 将提供一个 10 位数字键盘作为你的键盘。
pattern="[0-9]*"
也有效。这些箭头对我来说毫无意义。
0.06 或 +1.6e-2 或 1.55 等等呢?
所有这些都是数字吧?增量应该是什么?
你必须使用 step=”any”,增量将位于个位数,并以 1 为增量。如果你尝试使用 step=”2″ 进行增量,你将丢失浮点数(并且你的第一个增量将被四舍五入)。
1.6e-2 是一个简写符号,不是*严格意义*上的数字。或者我的数学理解错误了吗?
http://codepen.io/Stockings/pen/EarOPg
哦,我刚知道你可以使用 step 来定位小数位……哈哈。
step=”0.01″ 将使百分位数以 1 为增量。:)
希望对你有帮助!
step 属性定义了箭头执行的增加/减少量。Min 和 Max 可以(也可能应该)指定以定义允许的数字范围。
如果 step 被留空,它通常会参考 min 值来确定 step 应该是什么。
仅供参考;
如果你将 +1.6e2 这样的字面量传递给 FORTRAN 后端,它将被解释
为一个单精度实数。
3.1415926535d+0 作为浮点数,甚至还有
一个单精度复数,如 (3.2767e+2,-0.65e-2)。
FORTRAN 如何处理简写符号并不意味着简写符号是一个数字。它是一个数字的表示,浏览器不会将其解析为数字。仅仅因为某些编程语言对其进行解析并不改变它是什么。
再次强调,这是我个人的理解。我不想无礼——我只是想解释这种行为。
这正是为什么在几乎所有情况下都不应该覆盖浏览器默认设置的原因,除非它是更琐碎的(例如:颜色)或者更适合使用场景更改 ±1 到 ±5 或其他增量的默认值(例如,允许以 $5 为增量的小费)。
用户可能不仅仅使用一个浏览器,还会访问其他网站。如果他们访问另一个网站,并且他们保持该功能不变,而您却将其删除,那么您可能会遇到该用户的问题。:)
您似乎在 Opera 12 中测试了这个,Opera 12 已经过时了……为什么?为什么不使用最新的可用版本,比如 Opera 28?请考虑重新运行您的测试,并相应地更新本文中的兼容性表格,因为目前它并不完全是一个公平的比较。
回应 Mathias 的话。在旧版本的 Opera 中进行测试就像一些开发人员希望在他们的 Windows 机器上使用 Safari 并在 Safari 5 中打开一样。
也没有任何迹象表明旧版本的 IE 支持此输入(caniuse 报告称它在 IE10 中实现)。
好发现!这绝对是我疏忽了,我已经更新了帖子以反映 Opera 的最新版本。谢谢!
对于那些希望了解不同浏览器如何处理新输入类型而无需自己动手的人来说,这是一篇很棒的文章。我希望能看到更多这样的文章。
我认为文本中有一个小错误。
我理解 CSS 的方式是,任何没有设置为从右到左的 html 文档都会为所有输入元素设置 text-align: left。从右到左的文档(例如阿拉伯语页面)不会受到影响。
啊,马丁,说得好。我错误地遗漏了该句中的“not”一词,我已经更正了——谢谢!
如果有人想知道,Windows Phone 是这样处理数字输入的:http://i.imgur.com/8odp2Ig.png
它几乎与 Android 相同,但更简单。
如何在 Chrome 中删除日期输入的样式?
没有一个提供足够大的点击/点击目标来进行上下控制。Opera 最接近。
我猜对于旋转器,这取决于数字的用途。我曾经创建过一个东西(一个颜色选择器),在支持 type=”number” 之前,我尝试创建自己的旋转器,这样用户就可以轻松地对红色、绿色和蓝色字段进行微调。
我认为这些 UI 中缺少的关键要素是防止用户首先输入错误值的东西。在用户尝试提交表单时抱怨错误输入是一回事,但更人性化的是从一开始就防止错误发生。我个人宁愿没有机会犯错,也不愿意因犯错而受到责备!
我们最近一直在研究数字输入,一个很大的问题是,如果你输入任何不是 0-9 的内容,这些输入经常会使值为空。因此,如果你想将它用于可能需要空格或其他分隔符的数字,输入将失效。我们目前的方法是过滤掉除 0-9 之外的任何按键,以防止灾难发生。最好测试一下分隔符在哪里会导致问题,在我们最初的测试中,大多数浏览器都出现了问题。