无障碍树

无障碍功能树简介

Alice Boxhall
Alice Boxhall
Dave Gash
Dave Gash
Meggin Kearney
Meggin Kearney

假设您要构建一个仅面向屏幕阅读器用户的界面。在这里,您根本无需创建任何视觉界面,只需提供足够的信息供屏幕阅读器使用即可。

您要创建的是一种描述页面结构的 API,类似于 DOM API,但您只需提供较少的信息和较少的节点即可,因为其中很多信息仅适用于视觉呈现。该代码可能如下所示。

屏幕阅读器 DOM API 模拟

这基本上就是浏览器实际向屏幕阅读器呈现的内容。浏览器会获取 DOM 树,并将其修改为对辅助技术有用的表单。我们将此经过修改的树称为无障碍功能树

您可以将无障碍功能树视为类似于 90 年代的旧网页:几个图片、大量链接,可能还有一个字段和一个按钮。

20 世纪 90 年代风格的网页

在这种情况下,视觉扫描网页会给您带来与屏幕阅读器用户类似的体验。该界面确实存在,但简单明了,很像无障碍树界面。

大多数辅助技术都与无障碍功能树进行交互。流程如下所示。

  1. 应用(浏览器或其他应用)通过 API 向辅助技术公开其界面的语义版本。
  2. 辅助技术可能会使用它通过 API 读取的信息为用户创建备选界面呈现方式。例如,屏幕阅读器会创建一个界面,用户可以在其中听到应用的语音表述。
  3. 辅助技术还可以让用户以其他方式与应用互动。例如,大多数屏幕阅读器都提供钩子,以便用户轻松模拟鼠标点击或手指点按。
  4. 辅助技术会通过无障碍 API 将用户 intent(例如“点击”)转发回应用。然后,应用负责在原始界面上下文中适当地解释操作。

对于网络浏览器,每个方向都需要额外执行一个步骤,因为浏览器实际上是运行在其中的 Web 应用的平台。因此,浏览器需要将 Web 应用转换为无障碍功能树,并且必须确保根据辅助技术传入的用户操作,在 JavaScript 中触发适当的事件。

但这只是浏览器的全部责任。作为 Web 开发者,我们的工作只是了解这一过程,并开发利用此过程的网页,为用户打造无障碍体验。

为此,我们需要确保正确表达网页的语义:确保网页中的重要元素具有正确的可访问角色、状态和属性,并指定可访问的名称和说明。然后,浏览器可以让辅助技术访问这些信息,以打造量身定制的体验。

原生 HTML 中的语义

浏览器可以将 DOM 树转换为无障碍功能树,因为 DOM 的大部分内容都具有隐式语义含义。也就是说,DOM 使用浏览器能够识别的原生 HTML 元素,并且能够在各种平台上按预期运行。因此,系统会自动处理链接或按钮等原生 HTML 元素的无障碍功能。我们可以通过编写表达网页元素语义的 HTML 来利用此内置无障碍功能。

不过,有时我们会使用看起来像原生元素但实际上不是原生元素的元素。例如,此“按钮”根本就不是按钮。

给我来个墨西哥玉米卷饼

您可以通过多种方式在 HTML 中构建它;下面就展示了其中一种方式。

<div class="button-ish">Give me tacos</div>

如果我们不使用实际的按钮元素,屏幕阅读器就无法知道它当前位于什么位置。此外,我们还必须添加 tabindex 以便仅使用键盘的用户能够使用它,因为它目前的编码方式只能使用鼠标。

我们可以使用常规 button 元素(而非 div)轻松解决此问题。使用原生元素还有一个好处,就是可以为我们处理键盘互动。请注意,您不必因为使用原生元素而失去出色的视觉效果;您可以为原生元素设置样式,使其呈现您想要的外观,同时保留隐式语义和行为。

我们之前提到过,屏幕阅读器会读出元素的角色、名称、状态和值。通过使用合适的语义元素,可以涵盖角色、状态和值,但我们还必须确保元素的名称可被发现。

大致来说,名称有两种类型:

  • 可见标签,供所有用户使用,用于将元素与含义相关联;
  • 文本替代项,仅在不需要视觉标签时使用。

对于文本级元素,我们无需执行任何操作,因为根据定义,它将包含一些文本内容。不过,对于输入或控件元素以及图片等视觉内容,我们需要确保指定名称。事实上,为任何非文本内容提供文本替代项是 WebAIM 核对清单中的第一项

一种方法是遵循 Google 建议的“表单输入有相关文本标签”准则。您可以通过以下两种方式将标签与表单元素(例如复选框)相关联。这两种方法都会导致标签文本也成为复选框的点击目标,这对使用鼠标或触摸屏的用户也很有帮助。如需将标签与元素相关联,请执行以下操作之一:

  • 将输入元素放置在标签元素内
<label>
    <input type="checkbox">Receive promotional offers?
</label>

  • 使用标签的 for 属性并引用元素的 id
<input id="promo" type="checkbox">
<label for="promo">Receive promotional offers?</label>

正确为复选框添加标签后,屏幕阅读器可以报告该元素的角色为复选框,处于选中状态,且名称为“接收促销优惠?”。

VoiceOver 的屏幕文本输出,显示了复选框的语音标签