互动元素(包括表单控件、链接和按钮)默认情况下可聚焦且可使用 Tab 键切换。 可定位的元素是文档的顺序焦点导航顺序的一部分。其他元素是惰性元素,这意味着它们不具有互动性。借助 HTML 属性,您可以使互动元素变为非互动元素,也可以使非互动元素变为互动元素。
默认情况下,导航焦点顺序与视觉顺序(即源代码顺序)相同。有一些 HTML 属性可以改变此顺序,还有一些 CSS 属性可以改变内容的视觉顺序。使用 HTML 更改 Tab 键顺序或使用 CSS 更改视觉呈现顺序可能会损害用户体验。
请勿使用 CSS 和 HTML 更改感知到的和实际的 Tab 键顺序。以下两个示例表明,与视觉预期顺序不同的标签页顺序会让用户感到困惑,并会影响用户体验。
在此示例中,tabindex
属性的值导致标签页顺序混乱:
在此示例中,CSS 导致了标签页顺序与内容的视觉顺序之间的差异:
flex-flow: row-reverse;
声明已反转视觉顺序。
此外,CSS order 属性已应用于第六个字词“This”,这会在视觉上移动该字词。标签页序列是代码的顺序,该顺序不再与视觉顺序一致,导致键盘用户无法正常使用。
使非活动元素可交互
contenteditable
和 tabindex
属性是全局属性,可以添加到任何元素中,使这些元素在添加过程中可聚焦。可聚焦元素也可以通过鼠标或指针聚焦,方法是设置 autofocus
属性或通过脚本(例如使用 element.focus()
)聚焦。
tabindex
属性
全局 tabindex
属性(在属性中引入)可让原本无法接收焦点的元素获得焦点,通常是通过 Tab 键实现,因此得名。
tabindex
属性的值为整数。负值表示元素可聚焦但不可通过 Tab 键访问。值为 0
的 tabindex
会使元素可聚焦和可使用 Tab 键切换,并将应用该值的元素添加到源代码顺序中的顺序聚焦导航顺序。值为 1 或更大时,元素可聚焦且可使用 Tab 键定位,但会将其添加到优先的 Tab 键定位序列中,应避免使用。
在此页面上,分享按钮 <share-action>
是一个自定义元素。tabindex="0"
会将此通常无法聚焦的元素添加到键盘默认的 Tab 键顺序中:
<share-action authors="@front-end.social/@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, mastodon" role="button" tabindex="0">
<svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
<use href="#shareIcon" />
</svg>
<span>Share</span>
</share-action>
此网页上还有另一个自定义元素:本地导航具有一个 tabindex
值为负数的自定义元素:
<web-navigation-drawer type="standard" tabindex="-1">
如果 tabindex
属性的值为负数,则表示相应元素可聚焦但不可通过 Tab 键聚焦。该元素能够接收焦点(例如使用 HTMLElement.focus()
),但它不属于顺序焦点导航顺序。对于不可通过 Tab 键选择的焦点元素,惯例是使用 tabindex="-1"
。如果您向互动元素添加 tabindex="-1"
,该元素将不再可使用 Tab 键进行定位。
element.focus()
方法可用于将焦点设置到可聚焦的元素。浏览器会将聚焦的元素滚动到视图中。因此,请避免使用 element.focus({preventScroll:true})
,因为聚焦于不可见元素会导致用户体验不佳。
如果您想查询文档以了解哪个元素具有焦点,请使用只读的 Document.activeElement
属性。
tabindex
为 1
或更高级别的元素包含在单独的 Tab 序列中。如您在 Codepen 中所见,在按源顺序遍历常规序列(未设置 tabindex
或 tabindex="0"
)中的元素之前,标签页会先按从最低值到最高值的顺序遍历单独的序列:
如果 tabindex
具有正值,则会将元素置于优先的焦点序列中,这可能会导致焦点顺序混乱。
避免使用 tabindex
修改 DOM 顺序。更改后的 Tab 键顺序不仅会造成糟糕的用户体验,还会让开发者难以管理和维护。
contenteditable
属性
我们之前讨论过 contenteditable
属性。为任何元素设置 contenteditable="true"
都会使其可编辑、可聚焦,并成为 Tab 顺序的一部分。焦点行为与设置 tabindex="0"
类似,但不完全相同。嵌套的 contenteditable
元素可聚焦但不可通过 Tab 键聚焦。如需使嵌套的 contenteditable
元素可使用 Tab 键选择,请添加 tabindex="0"
,这会将其添加到顺序焦点导航顺序中。
为互动元素提供 autofocus
虽然布尔值 autofocus
是可以针对任何元素设置的全局属性,但它不会使惰性元素变为互动式元素。当网页加载时,具有 autofocus
属性的第一个可聚焦元素会获得焦点,前提是该元素已显示且未嵌套在 <dialog>
中。
自动将焦点设置在内容上可能会造成混淆。在表单控件上设置 autofocus
意味着表单控件会在网页加载时滚动到视图中。您的所有用户(包括屏幕阅读器用户和使用小视口的用户)可能都“看不到”表单的说明,甚至可能会滚动到表单控件通常可见的标签之外。autofocus
属性不会改变文档的顺序焦点导航顺序。系统会跳过序列中位于自动聚焦元素之前的元素。出于上述原因,建议不要添加 autofocus
属性。
“请勿使用 autofocus
”建议的例外情况是在 <dialog>
元素中包含 autofocus
属性。当对话框打开时,浏览器会自动将焦点放在 <dialog>
中的第一个可聚焦的互动元素上,这意味着无需向元素添加 autofocus
。如果您想确保对话框中的特定互动元素在对话框打开时获得焦点,请向该元素添加 autofocus
属性。
<dialog open>
<form method="dialog">
<button type="submit" autofocus>close</button>
</form>
</dialog>
在关闭按钮 <button>
上设置的 autofocus
属性允许它在对话框打开时接收焦点。作为对话框中的第一个元素,无论如何它都会获得焦点。默认情况下,当对话框打开时,对话框内的第一个可聚焦元素会获得焦点,除非对话框内的其他元素设置了 autofocus
属性。
使互动元素处于非活动状态
此外,还有一些 HTML 属性可用于从 Tab 键顺序中移除互动元素。包括将负 tabindex
添加到可聚焦元素、将 disabled
属性添加到支持的表单控件,以及将全局 inert
属性添加到容器,这些操作都会使元素无法通过 Tab 键进行定位。这三个属性不可互换。
负 tabindex
值
具有负值的 tabindex
属性可使元素可聚焦,但不可通过 Tab 键聚焦。虽然向默认可聚焦的元素(包括链接、按钮、表单控件和 contenteditable
元素)添加 tabindex="0"
不是必需的,但添加具有负值的 tabindex
会从顺序焦点导航顺序中移除通常可使用 Tab 键聚焦的元素。
负 tabindex
值可防止键盘用户将焦点放在互动式元素上,但不会停用该元素。指针用户仍然可以聚焦于该元素。如需停用某个元素,请使用 disabled
属性。
已停用
布尔值 disabled 属性可使应用了该属性的表单控件及其后代(如有)无法聚焦。已停用的表单控件无法聚焦,不会接收点击事件,并且在提交表单时不会提交。
disabled
不是全局属性。它适用于 <button>
、<input>
、<optgroup>
、<option>
、<select>
、<textarea>
、与表单关联的自定义元素和 <fieldset>
。当设置为 <optgroup>
或 <fieldset>
时,所有子表单控件都会被停用,但 <fieldset>
的第一个 <legend>
的内容除外。
支持 disabled
的元素也可以通过 :disabled
和 :enabled
伪类进行定位。使用 disabled
属性停用的元素通常会使用用户代理样式表设置为浅灰色,即使设置了 accent-color
也是如此。
作为布尔值属性,该属性的存在会停用原本已启用的元素;您无法将其设置为 false
。如需重新启用已停用的元素,必须移除该属性,通常使用 Element.removeAttribute('disabled')
。
借助 HTMLInputElement.disabled
属性,您可以检查输入是否处于停用状态。由于 disabled
不是全局属性,因此不会从 HTMLElement 继承,但每个支持的元素接口(例如 HTMLSelectElement
、HTMLTextareaElement
)都具有相同的只读属性。
disabled
属性不适用于通常为 inert
且通过 tabindex
或 contenteditable
变为可聚焦的元素,也不适用于 <form>
元素。如需停用这些元素,可以使用全局 inert
属性。
inert
属性
当向元素添加 inert
全局布尔值属性时,该元素和所有嵌套内容都会变为已停用,这意味着它们无法被点击或通过 Tab 键切换到。它们也会从无障碍树中移除。虽然 inert
可以应用于任何元素,但通常用于内容部分,例如屏幕外或以其他方式隐藏的内容。
将 disabled
应用于表单控件时,浏览器会提供默认样式,并且可以使用 :disabled
伪类设置样式。inert
属性不提供任何视觉指示器,也没有匹配的伪类(不过 [inert]
属性选择器匹配)。
在可见内容上使用 inert
而没有样式表明其处于非活动状态可能会导致糟糕的用户体验。由于屏幕阅读器用户无法访问惰性内容,因此当有视觉的屏幕阅读器用户看到屏幕上显示的内容无法通过无障碍工具访问时,可能会感到困惑。使用 CSS 使不活跃状态非常明显。
确保焦点永远不会移至不可见的内容。任何在屏幕外渲染且在获得焦点时不会自动进入视图的内容都应设为 inert。如果内容处于隐藏状态,但在获得焦点时会显示在视图中(例如“跳至内容”链接),则无需将其设为惰性。
检验您的掌握情况
测试您对对焦的了解程度。
如果某个元素无法聚焦,则会描述为?
如果元素具有 disabled
属性,则以下哪项为 true?