WAI-ARIA 基础

承接上一篇文章,有时创建涉及非语义 HTML 和动态 JavaScript 更新内容的复杂 UI 控件会很困难。WAI-ARIA 是一种技术,可以通过添加浏览器和辅助技术可以识别和使用的更多语义来解决此类问题,从而让用户了解正在发生的事情。在这里,我们将展示如何在基本级别使用它来提高无障碍性。

先决条件 对 HTML、CSS 和 JavaScript 的基本了解。理解本课程中的上一篇文章
目标 熟悉 WAI-ARIA,以及如何在需要时使用它来提供有用的额外语义以增强无障碍性。

什么是 WAI-ARIA?

让我们首先看看什么是 WAI-ARIA,以及它能为我们做什么。

一整套新的问题

随着 Web 应用程序变得越来越复杂和动态,一整套新的无障碍功能和问题开始出现。

例如,HTML 引入了一些语义元素来定义常见的页面功能(<nav><footer> 等)。在这些元素出现之前,开发人员会使用带 ID 或类的<div>,例如 <div class="nav">,但这些元素存在问题,因为没有简单的方法可以轻松地以编程方式找到特定的页面功能,例如主导航。

最初的解决方案是在页面顶部添加一个或多个隐藏链接,以链接到导航(或其他任何内容),例如

html
<a href="#hidden" class="hidden">Skip to navigation</a>

但这仍然不是很精确,并且只能在屏幕阅读器从页面顶部开始读取时使用。

作为另一个例子,应用程序开始提供复杂的控件,例如用于选择日期的日期选择器、用于选择值的滑块等。HTML 提供特殊的输入类型来呈现此类控件

html
<input type="date" /> <input type="range" />

这些控件最初支持得不好,而且在一定程度上仍然难以设置样式,导致设计师和开发人员选择自定义解决方案。一些开发人员没有使用这些原生功能,而是依赖于 JavaScript 库,这些库会将此类控件生成一系列嵌套的<div>,然后使用 CSS 设置样式,并使用 JavaScript 控制。

这里的问题是,它们在视觉上有效,但屏幕阅读器根本无法理解它们是什么,它们的用户只会被告知他们看到了一堆杂乱无章的元素,没有语义来描述它们的含义。

WAI-ARIA 登场

WAI-ARIA(Web 无障碍性倡议 - 可访问的富互联网应用程序)是 W3C 编写的规范,定义了一组可以应用于元素的额外 HTML 属性,以便在缺少语义的情况下提供额外语义并提高无障碍性。规范中定义了三个主要功能

角色

它们定义了元素是什么或做什么。许多角色是所谓的“地标角色”,它们在很大程度上复制了结构元素的语义值,例如 role="navigation" (<nav>) 或 role="complementary" (<aside>)。其他一些角色描述了不同的页面结构,例如 role="banner"role="search"role="tablist"role="tabpanel",这些角色在 UI 中很常见。

属性

它们定义了元素的属性,这些属性可以用来赋予它们额外的含义或语义。例如,aria-required="true" 指定表单输入需要填写才能有效,而 aria-labelledby="label" 允许您在元素上添加 ID,然后将其引用为页面上任何其他内容的标签,包括多个元素,这在使用 <label for="input"> 时是无法实现的。例如,您可以使用 aria-labelledby 指定包含在<div> 中的键描述是多个表格单元格的标签,或者您可以将其用作图像 alt 文本的替代方案 - 指定页面上现有的信息作为图像的 alt 文本,而不是必须在 alt 属性中重复它。您可以在文本替代 中看到此示例。

状态

定义元素当前条件的特殊属性,例如 aria-disabled="true",它告诉屏幕阅读器表单输入当前已禁用。状态与属性的区别在于,属性在应用程序生命周期中不会改变,而状态可能会改变,通常是通过 JavaScript 以编程方式进行的。

关于 WAI-ARIA 属性的一个重要点是,它们不会影响网页的任何内容,除了浏览器无障碍性 API(屏幕阅读器从中获取信息)公开的信息。WAI-ARIA 不会影响网页结构、DOM 等,尽管这些属性对于通过 CSS 选择元素很有用。

注意:您可以在 WAI-ARIA 规范中找到所有 ARIA 角色及其用法的有用列表,以及指向更多信息的链接 - 请参阅角色定义 - 在此网站上 - 请参阅ARIA 角色

该规范还包含所有属性和状态的列表,以及指向更多信息的链接 - 请参阅状态和属性定义(所有 aria-* 属性)

WAI-ARIA 在哪里受支持?

这个问题没有简单的答案。很难找到明确说明 WAI-ARIA 的哪些功能受支持以及在哪里受支持的资源,因为

  1. WAI-ARIA 规范中包含许多功能。
  2. 需要考虑的操作系统、浏览器和屏幕阅读器的组合有很多。

最后一点是关键 - 首先要使用屏幕阅读器,您的操作系统需要运行具有必要的无障碍性 API 的浏览器,这些 API 可以公开屏幕阅读器执行其工作所需的信息。大多数流行的操作系统都安装了一个或两个浏览器,屏幕阅读器可以与之配合使用。Paciello Group 有一篇相当最新的文章提供了这方面的数据 - 请参阅粗略指南:浏览器、操作系统和屏幕阅读器支持更新

接下来,您需要担心所讨论的浏览器是否支持 ARIA 功能并通过其 API 公开它们,还需要担心屏幕阅读器是否识别该信息并将其以有用的方式呈现给用户。

  1. 浏览器支持几乎是普遍的。
  2. 屏幕阅读器对 ARIA 功能的支持还没有达到这个水平,但最受欢迎的屏幕阅读器正在接近这个水平。您可以通过查看 Powermapper 的WAI-ARIA 屏幕阅读器兼容性 文章来了解支持水平。

在本文中,我们不会尝试涵盖每个 WAI-ARIA 功能及其确切的支持详细信息。相反,我们将涵盖您需要了解的最关键的 WAI-ARIA 功能;如果我们没有提及任何支持详细信息,您可以假设该功能得到了很好的支持。我们会明确提及任何例外情况。

注意:一些 JavaScript 库支持 WAI-ARIA,这意味着当它们生成 UI 功能(如复杂的表单控件)时,它们会添加 ARIA 属性来提高这些功能的无障碍性。如果您正在寻找用于快速 UI 开发的第三方 JavaScript 解决方案,您绝对应该将 UI 小部件的无障碍性作为做出选择时的重要因素。很好的例子是 jQuery UI(请参阅关于 jQuery UI:深层无障碍性支持)、ExtJSDojo/Dijit

您应该何时使用 WAI-ARIA?

我们之前讨论过促使 WAI-ARIA 诞生的部分问题,但本质上,WAI-ARIA 在四个主要领域非常有用

路标/地标

ARIA 的role 属性值可以充当地标,它们要么复制 HTML 元素的语义(例如,<nav>),要么超越 HTML 语义来提供指向不同功能区域的路标,例如,searchtablisttablistbox 等。

动态内容更新

屏幕阅读器在报告不断变化的内容时往往会遇到困难;使用 ARIA,我们可以使用 aria-live 来通知屏幕阅读器用户何时动态更新了内容区域:例如,通过页面中的 JavaScript从服务器获取新内容并更新 DOM

增强键盘无障碍性

有一些内置的 HTML 元素具有原生的键盘无障碍性;当其他元素与 JavaScript 一起使用来模拟类似的交互时,键盘无障碍性和屏幕阅读器报告会因此受到影响。在不可避免的情况下,WAI-ARIA 提供了一种方法,允许其他元素获得焦点(使用 tabindex)。

非语义控件的无障碍性

当使用一系列嵌套的 <div> 以及 CSS/JavaScript 来创建复杂的 UI 功能,或通过 JavaScript 极大地增强/更改原生控件时,无障碍性可能会受到影响 - 屏幕阅读器用户会发现很难弄清楚该功能的作用,如果没有语义或其他线索。在这些情况下,ARIA 可以帮助通过结合使用 buttonlistboxtablist 等角色,以及 aria-requiredaria-posinset 等属性来提供更多功能线索。

不过有一点要记住 - 您应该只在需要时使用 WAI-ARIA!理想情况下,您应该始终使用原生 HTML 功能 来提供屏幕阅读器所需的语义,以便告诉用户正在发生什么。有时这是不可能的,要么是因为您对代码的控制有限,要么是因为您正在创建没有简单的 HTML 元素来实现的复杂内容。在这种情况下,WAI-ARIA 可以成为一个有价值的增强无障碍性的工具。

但再次强调,只有在必要时才使用它!

注意:此外,尝试确保您使用各种真实用户测试您的网站 - 非残疾人、使用屏幕阅读器的人、使用键盘导航的人等等。他们将比您对网站的运行状况有更好的见解。

WAI-ARIA 的实际应用

在下一部分中,我们将更详细地介绍这四个方面,并提供实际示例。在继续之前,您应该配置一个屏幕阅读器测试环境,以便您可以在浏览示例时测试一些示例。

有关更多信息,请参阅我们关于测试屏幕阅读器 的部分。

路标/地标

WAI-ARIA 将role 属性 添加到浏览器,使您能够在网站上需要的地方添加额外的语义值。这在提供屏幕阅读器的信息以使用户能够找到常见的页面元素方面非常有用。让我们看一个例子 - 我们的website-no-roles 示例(查看实时示例)具有以下结构

html
<header>
  <h1></h1>
  <nav>
    <ul></ul>
    <form>
      <!-- search form -->
    </form>
  </nav>
</header>

<main>
  <article></article>
  <aside></aside>
</main>

<footer></footer>

如果你尝试在现代浏览器中使用屏幕阅读器测试示例,你将会得到一些有用的信息。例如,VoiceOver 会告诉你以下信息:

  • <header> 元素上 - "banner, 2 items"(它包含一个标题和 <nav>)。
  • <nav> 元素上 - "navigation 2 items"(它包含一个列表和一个表单)。
  • <main> 元素上 - "main 2 items"(它包含一篇文章和一个侧边栏)。
  • <aside> 元素上 - "complementary 2 items"(它包含一个标题和一个列表)。
  • 在搜索表单输入框上 - "Search query, insertion at beginning of text"。
  • <footer> 元素上 - "footer 1 item"。

如果你去 VoiceOver 的地标菜单(使用 VoiceOver 键 + U 访问,然后使用光标键循环浏览菜单选项),你会发现大多数元素都被很好地列出来了,以便快速访问。

Mac's VoiceOver menu for quick accessibility. Landmarks header and landmarks list including banner, navigation, main, and complementary.

但是,我们还可以做得更好。搜索表单是一个非常重要的地标,人们会想要找到它,但它没有列在地标菜单中,也没有被视为一个值得注意的地标,除了实际的输入被识别为搜索输入框(<input type="search">)。

让我们通过使用一些 ARIA 功能来改进它。首先,我们将添加一些 role 属性到我们的 HTML 结构中。你可以尝试复制我们的原始文件(参见 index.htmlstyle.css),或者导航到我们的 website-aria-roles 示例 (查看实时示例),它具有以下结构:

html
<header>
  <h1></h1>
  <nav role="navigation">
    <ul></ul>
    <form role="search">
      <!-- search form -->
    </form>
  </nav>
</header>

<main>
  <article role="article"></article>
  <aside role="complementary"></aside>
</main>

<footer></footer>

在这个示例中,我们还提供了一个额外的功能 - <input> 元素被赋予了属性 aria-label,它为其提供了一个描述性标签,即使我们没有包含 <label> 元素,屏幕阅读器也会读出这个标签。在这样的情况下,这非常有用 - 像这样的搜索表单是一个非常常见且易于识别的功能,添加一个可视标签会破坏页面设计。

html
<input
  type="search"
  name="q"
  placeholder="Search query"
  aria-label="Search through site content" />

现在,如果我们使用 VoiceOver 查看这个示例,我们会看到一些改进:

  • 搜索表单被识别为一个单独的项目,无论是浏览页面时还是在地标菜单中。
  • 当表单输入被选中时,aria-label 属性中包含的标签文本会被读出来。

除此之外,该网站更有可能对 IE8 等旧版浏览器的用户可访问;为了这个目的,包含 ARIA 角色是值得的。如果出于某种原因,你的网站只是使用 <div> 构建的,你绝对应该包含 ARIA 角色来提供这些急需的语义!

搜索表单改进后的语义展示了 ARIA 在 HTML 可用语义之外所能实现的功能。你将在下面的内容中看到更多关于这些语义和 ARIA 属性/特性功能的信息,特别是在 非语义控件的可访问性 部分。不过现在,让我们看看 ARIA 如何帮助处理动态内容更新。

动态内容更新

加载到 DOM 中的内容可以使用屏幕阅读器轻松访问,从文本内容到附加到图像的替代文本。因此,传统的静态网站,其内容主要为文本,对于视力障碍者来说很容易做到可访问。

问题是,现代 Web 应用程序通常不仅仅是静态文本 - 它们通常通过从服务器获取新内容并更新 DOM 来更新页面的某些部分。这些有时被称为 **实时区域**。

让我们看一个简单的例子 - 参见 aria-no-live.html(以及 查看实时示例)。在这个示例中,我们有一个简单的随机引语框

html
<section>
  <h1>Random quote</h1>
  <blockquote>
    <p></p>
  </blockquote>
</section>

我们的 JavaScript 使用 fetch() API 通过包含一系列随机引语及其作者的 JSON 文件来加载内容。完成之后,我们启动一个 setInterval() 循环,每 10 秒将一个新的随机引语加载到引语框中

js
const intervalID = setInterval(showQuote, 10000);

这工作正常,但对于可访问性来说并不理想 - 内容更新没有被屏幕阅读器检测到,因此他们的用户不知道发生了什么。这是一个相当简单的例子,但想象一下,如果你正在创建一个具有大量不断更新内容的复杂 UI,比如聊天室、策略游戏 UI 或者实时更新的购物车显示 - 在没有某种方法提醒用户更新的情况下,无法以任何有效的方式使用该应用程序。

幸运的是,WAI-ARIA 提供了一种有用的机制来提供这些提醒 - aria-live 属性。将其应用于某个元素会导致屏幕阅读器读出被更新的内容。内容被读出的紧急程度取决于属性值:

off

默认值。不应该宣布更新。

polite

只有在用户处于空闲状态时才应宣布更新。

assertive

应尽快向用户宣布更新。

我们希望你复制 aria-no-live.htmlquotes.json,并更新你的 <section> 开启标签,如下所示:

html
<section aria-live="assertive"></section>

这会导致屏幕阅读器在内容被更新时读出内容。

注意:如果你尝试从 file:// URL(例如,如果你只是通过直接加载到浏览器中(通过双击等)来加载文件)进行 HTTP 请求,大多数浏览器会抛出一个安全异常。参见 如何设置本地测试服务器

这里还有一个额外的考虑 - 只有更新的那部分文本会被读出来。如果我们始终读出标题,这样用户可以记住正在读出的内容,也许会更好。为了做到这一点,我们可以将 aria-atomic 属性添加到该部分。再次更新你的 <section> 开启标签,如下所示:

html
<section aria-live="assertive" aria-atomic="true"></section>

aria-atomic="true" 属性告诉屏幕阅读器将整个元素内容作为一个原子单元读出来,而不仅仅是更新的部分。

注意:你可以在 aria-live.html (查看实时示例) 中看到完成的示例。

注意:aria-relevant 属性对于控制实时区域更新时读出内容也非常有用。例如,你只能让内容添加或删除被读出来。

增强键盘无障碍性

如本模块其他地方所述,HTML 在可访问性方面的一大优势是内置的键盘可访问性,例如按钮、表单控件和链接。通常情况下,你可以使用 Tab 键在控件之间移动,使用 Enter/Return 键选择或激活控件,有时还需要使用其他控件(例如,使用向上和向下箭头键在 <select> 框中的选项之间移动)。

但是,有时你最终需要编写一些代码,这些代码要么使用非语义元素作为按钮(或其他类型的控件),要么使用可聚焦控件来实现与预期目的不符的功能。你可能在尝试修复你继承的一些不良代码,或者你可能正在构建一些需要这种功能的复杂小部件。

在将不可聚焦的代码变为可聚焦的方面,WAI-ARIA 用一些新的值扩展了 tabindex 属性:

  • tabindex="0" - 如上所述,此值允许通常不可聚焦的元素变为可聚焦的。这是 tabindex 最有用的值。
  • tabindex="-1" - 这允许通常不可聚焦的元素通过编程方式获得焦点,例如通过 JavaScript,或者作为链接的目标。

我们在我们的 HTML 可访问性文章中更详细地讨论了这一点,并展示了一个典型的实现 - 参见 重新构建键盘可访问性

非语义控件的无障碍性

这紧随上一节 - 当一系列嵌套的 <div> 与 CSS/JavaScript 一起使用来创建复杂的 UI 功能,或者原生控件通过 JavaScript 大幅增强/改变时,不仅键盘可访问性会受到影响,屏幕阅读器用户也会发现很难理解该功能的作用,因为没有语义或其他线索。在这种情况下,ARIA 可以帮助提供这些缺失的语义。

表单验证和错误提醒

首先,让我们回顾一下我们在 CSS 和 JavaScript 可访问性文章中首次看到的表单示例(阅读 保持非侵入性 以获取完整回顾)。在本节的末尾,我们展示了我们在错误消息框上添加了一些 ARIA 属性,该消息框会在你尝试提交表单时显示任何验证错误

html
<div class="errors" role="alert" aria-relevant="all">
  <ul></ul>
</div>
  • role="alert" 会自动将它所应用的元素变成一个实时区域,因此对它的更改会被读出来;它还在语义上将它识别为一个提醒消息(重要的时效性/上下文相关信息),并且代表了一种向用户发出提醒的更佳、更易访问的方式(像 alert() 调用这样的模态对话框存在许多可访问性问题;参见 WebAIM 的 弹出窗口)。
  • aria-relevant 的值为 all,它指示屏幕阅读器在对错误列表进行任何更改时(即添加或删除错误时)读出错误列表的内容。这很有用,因为用户会想知道剩下的错误是什么,而不仅仅是列表中添加了什么或删除了什么。

我们可以进一步使用 ARIA,并提供更多验证帮助。如何指示哪些字段是必需的,以及年龄的范围应该是多少呢?

  1. 在这一点上,请复制我们的 form-validation.htmlvalidation.js 文件,并将它们保存到本地目录中。
  2. 在文本编辑器中打开它们,并查看代码是如何工作的。
  3. 首先,在 <form> 开启标签之前添加一个段落,就像下面这个一样,并在表单 <label> 上标记一个星号。这通常是我们为视力正常的用户标记必填字段的方式。
    html
    <p>Fields marked with an asterisk (*) are required.</p>
    
  4. 这在视觉上是有意义的,但对于屏幕阅读器用户来说并不容易理解。幸运的是,WAI-ARIA 提供了 aria-required 属性,以便让屏幕阅读器提示他们告诉用户哪些表单输入需要填写。请按以下方式更新 <input> 元素:
    html
    <input type="text" name="name" id="name" aria-required="true" />
    
    <input type="number" name="age" id="age" aria-required="true" />
    
  5. 如果你现在保存该示例并使用屏幕阅读器测试它,你应该听到类似 "Enter your name star, required, edit text" 的内容。
  6. 为屏幕阅读器用户和有视力用户提供年龄值应为多少的提示可能也很有用。 这通常以工具提示或占位符的形式显示在表单字段中。 WAI-ARIA 确实包含 aria-valueminaria-valuemax 属性来指定最小值和最大值,屏幕阅读器支持本机 minmax 属性。 另一个得到良好支持的功能是 HTML placeholder 属性,它可以包含在输入中未输入任何值时显示的消息,并且可以由一些屏幕阅读器朗读。 像这样更新您的数字输入
    html
    <label for="age">Your age:</label>
    <input
      type="number"
      name="age"
      id="age"
      placeholder="Enter 1 to 150"
      required
      aria-required="true" />
    

始终为每个输入包含一个 <label>。 虽然一些屏幕阅读器会宣布占位符文本,但大多数不会。 为表单控件提供可访问名称的可接受替代方法包括 aria-labelaria-labelledby。 但是,带有 for 属性的 <label> 元素是首选方法,因为它为所有用户提供了可用性,包括鼠标用户。

注意:您可以在 form-validation-updated.html 中查看完成的示例。

WAI-ARIA 还支持一些高级表单标记技术,超越了经典的 <label> 元素。 我们已经讨论过使用 aria-label 属性来提供标签,我们不希望标签对有视力用户可见(参见上面的 路标/地标 部分)。 一些其他标记技术使用其他属性,例如 aria-labelledby,如果您想指定一个非 <label> 元素作为标签或用同一个标签标记多个表单输入,以及 aria-describedby,如果您想将其他信息与表单输入相关联并将其也读出来。 有关更多详细信息,请参阅 WebAIM 的高级表单标记文章

还有许多其他有用的属性和状态,用于指示表单元素的状态。 例如,aria-disabled="true" 可用于指示表单字段已禁用。 许多浏览器会跳过禁用的表单字段,从而导致屏幕阅读器无法读出它们。 在某些情况下,禁用的元素会被感知,因此建议包含此属性,以让屏幕阅读器知道禁用的表单控件实际上是被禁用的。

如果输入的禁用状态可能发生变化,那么在它发生时以及结果是什么时也很有必要进行指示。 例如,在我们的 form-validation-checkbox-disabled.html 演示中,有一个复选框,当选中时,会启用另一个表单输入以允许输入更多信息。 我们已经设置了一个隐藏的实时区域

html
<p class="hidden-alert" aria-live="assertive"></p>

它使用绝对定位从视图中隐藏。 当选中/取消选中时,我们更新隐藏的实时区域内的文本,以告知屏幕阅读器用户选中此复选框的结果,以及更新 aria-disabled 状态和一些视觉指示器

js
function toggleMusician(bool) {
  const instruItem = formItems[formItems.length - 1];
  if (bool) {
    instruItem.input.disabled = false;
    instruItem.label.style.color = "#000";
    instruItem.input.setAttribute("aria-disabled", "false");
    hiddenAlert.textContent =
      "Instruments played field now enabled; use it to tell us what you play.";
  } else {
    instruItem.input.disabled = true;
    instruItem.label.style.color = "#999";
    instruItem.input.setAttribute("aria-disabled", "true");
    instruItem.input.removeAttribute("aria-label");
    hiddenAlert.textContent = "Instruments played field now disabled.";
  }
}

将非语义按钮描述为按钮

在本课程中,我们已经多次提到了(以及使用其他元素来伪造按钮、链接或表单元素背后的可访问性问题)按钮、链接或表单元素的本机可访问性(请参阅 HTML 可访问性文章中的 UI 控件,以及上面的 增强键盘可访问性)。 基本上,在许多情况下,您可以使用 tabindex 和一些 JavaScript 将键盘可访问性添加回来,而不会遇到太多麻烦。

但是屏幕阅读器呢? 它们仍然不会将这些元素视为按钮。 如果我们在屏幕阅读器中测试我们的 fake-div-buttons.html 示例,我们的伪按钮将使用诸如“点击我!,组”之类的短语进行报告,这显然令人困惑。

我们可以使用 WAI-ARIA 角色来解决这个问题。 制作 fake-div-buttons.html 的本地副本,并向每个按钮 <div> 添加 role="button",例如

html
<div data-message="This is from the first button" tabindex="0" role="button">
  Click me!
</div>

现在,当您使用屏幕阅读器尝试此操作时,您将使用诸如“点击我!,按钮”之类的短语来报告按钮。 虽然这要好得多,但您仍然需要添加用户期望的所有本机按钮功能,例如处理 enter 和点击事件,如 button 角色文档 中所述。

注意:但是,请不要忘记,尽可能使用正确的语义元素始终是最好的。 如果你想创建一个按钮,并且可以使用 <button> 元素,你应该使用 <button> 元素!

引导用户完成复杂的窗口小部件

还有许多其他 角色 可以将非语义元素结构识别为超越标准 HTML 中可用内容的常见 UI 功能,例如 comboboxslidertabpaneltree。 您可以在 Deque 大学代码库 中看到几个有用的示例,这些示例可以帮助您了解如何使这些控件变得可访问。

让我们来看一个我们自己的例子。 我们将回到我们简单的绝对定位选项卡式界面(参见我们的 CSS 和 JavaScript 可访问性文章中的 隐藏内容),您可以在 选项卡式信息框示例 中找到它(参见 源代码)。

这个示例本身在键盘可访问性方面运行良好——您可以轻松地在不同的选项卡之间切换,并选择它们来显示选项卡内容。 它也很容易访问——即使您看不到屏幕上发生了什么,您也可以滚动浏览内容并使用标题进行导航。 但是,内容究竟是什么并不那么明显——屏幕阅读器当前将内容报告为链接列表,以及三个标题的一些内容。 它不会让您了解内容之间的关系。 始终为用户提供更多关于内容结构的线索是件好事。

为了改进,我们创建了示例的新版本,名为 aria-tabbed-info-box.html查看它正在运行)。 我们已经更新了选项卡式界面的结构,如下所示

html
<ul role="tablist">
  <li
    class="active"
    role="tab"
    aria-selected="true"
    aria-setsize="3"
    aria-posinset="1"
    tabindex="0">
    Tab 1
  </li>
  <li
    role="tab"
    aria-selected="false"
    aria-setsize="3"
    aria-posinset="2"
    tabindex="0">
    Tab 2
  </li>
  <li
    role="tab"
    aria-selected="false"
    aria-setsize="3"
    aria-posinset="3"
    tabindex="0">
    Tab 3
  </li>
</ul>
<div class="panels">
  <article class="active-panel" role="tabpanel" aria-hidden="false"></article>
  <article role="tabpanel" aria-hidden="true"></article>
  <article role="tabpanel" aria-hidden="true"></article>
</div>

注意:这里最显着的变化是我们删除了示例中最初存在的链接,并且只使用列表项作为选项卡——这样做是为了让屏幕阅读器用户不那么困惑(链接实际上并没有带您去任何地方;它们只是改变了视图),并且它允许 setsize/position 在 set 功能中更好地工作——当这些功能放在链接上时,浏览器一直报告“1 of 1”,而不是“1 of 3”、“2 of 3”等等。

使用的 ARIA 功能包括

新角色 — tablisttabtabpanel

这些标识了选项卡式界面的重要区域——选项卡的容器、选项卡本身以及相应的选项卡面板。

aria-selected

定义当前选中的选项卡。 当用户选择不同的选项卡时,此属性在不同选项卡上的值将通过 JavaScript 更新。

aria-hidden

隐藏元素,使其不被屏幕阅读器读出。 当用户选择不同的选项卡时,此属性在不同选项卡上的值将通过 JavaScript 更新。

tabindex="0"

由于我们已经删除了链接,因此我们需要为列表项提供此属性,以使其具有键盘焦点。

aria-setsize

此属性允许您向屏幕阅读器指定元素是系列的一部分,以及系列中有多少个项目。

aria-posinset

此属性允许您指定元素在系列中的位置。 与 aria-setsize 一起,它为屏幕阅读器提供了足够的信息来告诉您您当前位于项目“1 of 3”等。 在许多情况下,浏览器应该能够从元素层次结构中推断出此信息,但这确实有助于提供更多线索。

在我们的测试中,这种新的结构确实在总体上有所改进。 选项卡现在被识别为选项卡(例如,屏幕阅读器会说“选项卡”),选中的选项卡通过在选项卡名称中读出“选中”来指示,屏幕阅读器还会告诉您您当前位于哪个选项卡编号。 此外,由于 aria-hidden 设置(只有未隐藏的选项卡的 aria-hidden="false" 设置),未隐藏的内容是您唯一可以向下导航的内容,这意味着选中的内容更容易找到。

注意:如果您明确地不希望屏幕阅读器读出任何内容,可以为它们提供 aria-hidden="true" 属性。

测试您的技能!

您已经到达了本文的结尾,但是您还记得最重要的信息吗? 您可以在继续之前找到一些进一步的测试来验证您是否保留了此信息——请参阅 测试您的技能:WAI-ARIA

摘要

本文绝不是涵盖了 WAI-ARIA 中所有可用的内容,但它应该为您提供了足够的信息来了解如何使用它,并了解一些需要它的最常见模式。

另请参阅

  • Aria 状态和属性:所有 aria-* 属性
  • WAI-ARIA 角色:ARIA 角色的类别以及 MDN 上涵盖的角色
  • HTML 中的 ARIA 在 W3C 上:一个规范,它为每个 HTML 功能定义浏览器隐式应用于它的可访问性 (ARIA) 语义以及在需要额外语义时可以在它上面设置的 WAI-ARIA 功能
  • Deque 大学代码库:一个非常有用和实用的示例库,展示了使用 WAI-ARIA 功能使复杂 UI 控件变得可访问。
  • WAI-ARIA 创作实践 在 W3C 上:来自 W3C 的一个非常详细的设计模式,解释了如何在实现不同类型的复杂 UI 控件的同时,使用 WAI-ARIA 功能使其变得可访问。