带有 inert 属性的非交互式元素

元素可以通过多种方式进行交互;它们可以被聚焦、点击、编辑或选中。屏幕阅读器等辅助技术也与它们交互。如果您想禁用网页中某个部分的这些所有交互怎么办?inert 属性可以实现这一点。

现有解决方案

禁用所有交互最基本的方法是使用 HTML disabled 属性,它可以防止聚焦、点击、编辑或选中。然而,它仅适用于表单控件,并且不一定会将控件隐藏于辅助技术。如果您想在表单控件以外的元素上执行此操作怎么办?

为防止聚焦,tabindex="-1" 是一个常用的选项,但它并不理想,因为在容器元素上设置该属性并不能阻止其子元素被聚焦,也无法阻止通过鼠标点击聚焦。如果您想阻止整个区域的键盘聚焦,则该区域中的每个可聚焦元素都需要设置该属性。

为了防止点击,CSS 属性 pointer-events: none 可能是一个选项,但除非您也对元素设置了 tabindex="-1",否则仍然可以通过 Tab 键聚焦并与之交互。

为防止选中,CSS 属性 user-select: none 是最常见的选项。

为了防止编辑,如果您正在使用 contenteditable,则需要手动移除 contenteditable 属性。如果是表单控件,则需要手动设置 disabled 属性。

所有这些方法都比较繁琐,并且无法将该部分从辅助工具中隐藏,而当整个部分变为非交互式时,这种隐藏可能是合适的。目前可以通过在相关部分设置 aria-hidden="true" 来实现这一点。

这就是为什么 inert 属性被添加到 HTML 中的原因,它是一种有效的方式来禁用上述所有交互并从辅助技术中隐藏元素。

什么是 inert 属性?

inert 属性最初是在 dialog 元素的上下文中指定的,大约在 10 年前,其主要用例是使模态对话框后面的内容变为非交互式。后来由于缺乏采用而被移除。最近的开发者请求使其在几年后被重新提出。然而,该定义的主要问题在于与模态对话框交互时的复杂性和性能。这就是为什么标准中进行了更改,以使用基于 CSS 的方法来定义惰性节点。

根据HTML 规范,当一个节点是惰性的时

  • 命中测试(Hit-testing)的行为必须如同 CSS 属性 ‘pointer-events’ 被设置为 ‘none’。
  • 文本选择功能必须如同 CSS 属性 ‘user-select’ 被设置为 ‘none’。
  • 如果它是可编辑的,该节点的行为如同不可编辑。

除此之外

  • 它不可聚焦。
  • 对于辅助技术而言,它的行为类似于 aria-hidden="true"

使用示例:一个轮播图

让我们构建一个多页轮播图

您会注意到,您仍然可以与非活动页面中的链接/输入等进行交互。这种不希望发生的行为可以通过 inert 属性来阻止。在切换活动页面的 switchToIndex 方法中,我们可以添加两行代码来解决这个问题。

this.items 是一个表示每个幻灯片的 HTML 元素数组,第一行使每个幻灯片变为惰性,第二行使活动幻灯片变为非惰性。

  switchToIndex(index) {
    [...]
    this.items.forEach(item => item.inert = true);
    this.items[index].inert = false;
  }

请注意,我们使用了 inert DOM 属性。当设置为某个值时,它等同于 element.toggleAttribute("inert", value)

为了在旧版浏览器中获得支持,在 inert 属性得到广泛支持之前,您可能需要使用一个polyfill(兼容性补丁)

最后,建议添加视觉提示,表明某个元素是惰性的。让我们降低非活动幻灯片的透明度。

.carousel-item[inert] {
  opacity: 0.6;
}

这是最终效果展示

如您所见,非活动幻灯片不再是交互式的,但它们仍然可见。

浏览器支持

更多资源

在本文中,我们概述了新的 inert 属性。这里有一些您可能想要查看的有趣额外资源

如有任何疑问,请随时在 Twitter 上联系 @therealntim。要报告任何问题,请提交一个错误,阻止 bug 165279