手机等小屏幕设备通常具有触摸屏。笔记本电脑和台式机等大屏设备通常配有鼠标或触控板等硬件。很容易将小屏幕等同于触摸屏,将大屏幕等同于指针。
但实际情况则要更微妙。某些笔记本电脑具有触摸屏功能。用户可以与触摸屏和/或触控板互动。同样,您也可以在平板电脑等触摸屏设备上使用外接键盘或鼠标。
不要尝试根据屏幕尺寸推断输入机制,而是使用 CSS 中的媒体功能。
指针
您可以使用 pointer
媒体功能测试以下三个可能的值:none
、coarse
和 fine
。
如果浏览器报告的 pointer
值为 none
,则表示用户可能是在使用键盘与您的网站互动。
如果浏览器报告的 pointer
值为 coarse
,则表示主要输入机制不是非常准确。触摸屏上的手指是粗略指针。
如果浏览器报告的 pointer
值为 fine
,则表示主要输入机制能够进行精细控制。鼠标或触控笔是一根精细指针。
您可以调整界面元素的大小,使其适合 pointer
值。请尝试使用不同类型的设备访问此网站,看看界面如何进行调整。
在此示例中,针对粗略指针将按钮调大了:
button {
padding: 0.5em 1em;
}
@media (pointer: coarse) {
button {
padding: 1em 2em;
}
}
您也可以针对精细指针缩小元素,但这样做时请务必小心:
@media (pointer: fine) {
button {
padding: 0.25em 0.5em;
}
}
即使用户拥有可进行精细控制的主要输入机制,在缩减交互元素的大小之前也要三思而后行。菲茨定律仍然适用。目标越小,就算是精细指针也要集中注意力。更大的目标区域对所有人都有益,无论用户使用什么指控设备都是如此。
任意指针
pointer
媒体功能可报告主要输入机制的精细程度。但是,许多设备具有多种输入机制。有可能用户同时使用触摸屏和鼠标与您的网站互动。
any-pointer
与 pointer
媒体功能的不同之处在于,它会报告任何指控设备是否通过测试。
any-pointer
值为 none
表示没有可用的指控设备。
any-pointer
值为 coarse
表示至少有一个指控设备不太准确。但这可能不是主要的输入机制。
any-pointer
值为 fine
表示至少有一个指控设备能够进行精细控制。但再次强调,这可能不是主要的输入机制。
由于如果任何输入机制通过测试,any-pointer
媒体查询会报告肯定结果,因此浏览器有可能针对 any-pointer: fine
报告结果,同时报告 any-pointer: coarse
的结果。在这种情况下,媒体查询的顺序非常重要。以后者为准。
在此示例中,如果设备同时具有精确和粗略输入机制,则会应用粗略样式。
@media (any-pointer: fine) {
button {
padding: 0.5em 1em;
}
}
@media (any-pointer: coarse) {
button {
padding: 1em 2em;
}
}
悬停
hover
媒体功能会报告主要输入机制是否可以将鼠标悬停在元素上。这通常意味着屏幕上有某种由鼠标或触控板控制的光标。
与区分精确指针和粗略指针的 pointer
媒体功能不同,hover
媒体功能是二进制的。如果主要输入设备能够将鼠标悬停在元素上,它会报告 hover
值。否则,值为 none
。
在此示例中,一些补充图标在鼠标指针悬停时可用,但前提是主要输入设备能够将鼠标悬停在某个元素上。
button .extra {
visibility: visible;
}
@media (hover: hover) {
button .extra {
visibility: hidden;
}
button:hover .extra {
visibility: visible;
}
}
如果您将鼠标悬停在该按钮上,系统就会显示该图标。但是,如果您使用键盘按 Tab 键转到按钮,图标将保持不可见状态。使用键盘时,您会获得焦点,而不是悬停。装有鼠标的桌面设备会报告主要输入机制能够悬停鼠标,这是真的。但是,任何在连接鼠标时使用键盘的用户将无法受益于 :hover
样式。因此,最好组合使用 :hover
和 :focus
样式来涵盖这两种互动。
button .extra {
visibility: visible;
}
@media (hover: hover) {
button .extra {
visibility: hidden;
}
button:is(:hover, :focus) .extra {
visibility: visible;
}
}
即使主要输入设备能够将鼠标悬停在元素上,也要小心隐藏悬停互动背后的信息。信息的曝光度会降低。请勿使用悬停功能来隐藏重要信息或重要界面元素。
任何悬停
hover
媒体查询仅报告主要输入机制。某些设备有多种输入机制:触摸屏、鼠标、键盘、触控板。
就像 any-pointer
报告任何输入机制一样,如果任何可用的输入机制能够将鼠标悬停在元素上,则 any-hover
将为 true。
如果您决定反转上例中的逻辑,则可以将悬停样式设为默认悬停样式,如果 any-hover
的值为 none
,则将其移除。
button .extra {
visibility: hidden;
}
button:hover .extra,
button:focus .extra {
visibility: visible;
}
@media (any-hover: none) {
button .extra {
visibility: visible;
}
}
在没有可悬停的输入机制的设备上,额外图标始终可见。
虚拟键盘
用户使用光标和手指来浏览界面,但在输入信息时,他们需要用到键盘。如果用户的设备连接了实体键盘,没关系,但如果他们使用的是触摸屏设备,情况就更复杂了。这些设备提供屏幕虚拟键盘。
输入类型
与实体键盘不同,虚拟键盘可以根据预期输入进行定制。如果您提供了有关预期输入源的信息,设备可以提供最合适的虚拟键盘。
HTML5 输入类型是描述 input
元素的理想方式。type
属性接受 email
、number
、tel
、url
等值。
<label for="email">Email</label>
<input type="email" id="email">
<label for="number">Number</label>
<input type="number" id="number">
<label for="tel">Tel</label>
<input type="tel" id="tel">
<label for="url">URL</label>
<input type="url" id="url">
输入法
浏览器支持
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
- <ph type="x-smartling-placeholder">
inputmode
属性可让您精细控制虚拟键盘。例如,有一个 input
type
的值为 number
,您可以使用 inputmode
属性来区分整数和小数。
如果您要输入整数(例如某人的年龄),请使用 inputmode="numeric"
。
<label for="age">Age</label>
<input type="number" id="age" inputmode="numeric">
如果您要输入包含小数位的数字(例如价格),请使用 inputmode="decimal"
。
<label for="price">Price</label>
<input type="number" id="price" inputmode="decimal">
自动补全
没有人喜欢填写表单。作为设计人员,您可以允许用户自动填充表单字段,从而改善他们的体验。autocomplete
属性为改进联系表单、登录表单和结账表单提供了大量选项。
<label for="name">Name</label>
<input type="text" id="name" autocomplete="name">
<label for="country">Country</label>
<input type="text" id="country" autocomplete="country">
<label for="email">Email</label>
<input type="email" id="email" autocomplete="email">
这些 HTML 属性(type
、inputmode
和 autocomplete
)是对表单字段的补充,但它们却对用户体验大有裨益。通过预测用户的设备功能并做出响应,您可以赋予用户强大的能力。如需了解更详细的信息,我们专门提供了一门课程来帮您学习表单。
在本课程中,我们将了解一些常见的接口模式。
检查您的理解情况
测试您对互动的了解情况
您应该使用哪项功能,而不是尝试根据屏幕尺寸推断用户的输入类型?
handheld
prompt()
询问用户@media (pointer)
和 @media (any-pointer)
有什么区别?
哪种输入类型会向用户显示更合适的虚拟键盘?
type="tel"
type="url"
type="email"
type="number"