WAI-ARIA 基础
承接上一篇文章,有时,制作涉及非语义化 HTML 和动态 JavaScript 更新内容的复杂 UI 控件可能会很困难。WAI-ARIA 是一种可以帮助解决此类问题的技术,它通过添加浏览器和辅助技术可以识别和使用的进一步语义,让用户了解正在发生的事情。在这里,我们将展示如何以基本方式使用它来提高可访问性。
什么是 WAI-ARIA?
让我们首先了解 WAI-ARIA 是什么,以及它能为我们做什么。
一系列全新的问题
随着 Web 应用程序变得越来越复杂和动态,一系列新的可访问性功能和问题开始出现。
例如,HTML 引入了许多语义元素来定义常见的页面功能(<nav>
、<footer>
等)。在这些元素可用之前,开发人员会使用带有 ID 或类的 <div>
,例如 <div class="nav">
,但这带来了问题,因为无法通过编程方式轻松找到特定的页面功能,例如主导航。
最初的解决方案是在页面顶部添加一个或多个隐藏链接,以链接到导航(或其他内容),例如
<a href="#hidden" class="hidden">Skip to navigation</a>
但这仍然不是很精确,并且只能在屏幕阅读器从页面顶部读取时使用。
另一个例子是,应用程序开始出现复杂的控件,例如用于选择日期的日期选择器、用于选择值的滑块等。HTML 提供了特殊的输入类型来呈现此类控件
<input type="date" /> <input type="range" />
这些控件最初支持不佳,而且对其进行样式设置过去和现在在较小程度上仍然很困难,这导致设计人员和开发人员选择自定义解决方案。一些开发人员没有使用这些原生功能,而是依赖 JavaScript 库,这些库将此类控件生成为一系列嵌套的 <div>
,然后使用 CSS 进行样式设置并使用 JavaScript 进行控制。
这里的问题是它们在视觉上是有效的,但屏幕阅读器完全无法理解它们是什么,并且它们的用户只被告知他们看到的是一堆没有任何语义来描述它们含义的元素。
WAI-ARIA 登场
WAI-ARIA(Web 可访问性倡议 - 可访问富互联网应用)是 W3C 编写的规范,定义了一组可应用于元素的额外 HTML 属性,以提供额外的语义并改进可访问性(在可访问性不足的地方)。规范中定义了三个主要功能
- 角色
-
这些定义了元素的性质或功能。其中许多是所谓的地标角色,它们在很大程度上复制了结构元素的语义值,例如
role="navigation"
(<nav>
)、role="banner"
(文档<header>
)、role="complementary"
(<aside>
)或role="search"
(<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 的哪些功能受支持以及在哪里受支持,因为
- WAI-ARIA 规范中有很多功能。
- 需要考虑操作系统、浏览器和屏幕阅读器的许多组合。
最后一点是关键——首先要使用屏幕阅读器,您的操作系统需要运行具有必要可访问性 API 的浏览器,以公开屏幕阅读器完成其工作所需的信息。大多数流行的操作系统都有一两个浏览器可以与屏幕阅读器配合使用。Paciello Group 有一篇相当新的文章提供了这方面的数据——请参阅粗略指南:浏览器、操作系统和屏幕阅读器支持更新。
接下来,您需要担心相关浏览器是否支持 ARIA 功能并通过其 API 公开它们,以及屏幕阅读器是否识别该信息并以有用的方式呈现给其用户。
- 浏览器支持几乎是普遍的。
- 屏幕阅读器对 ARIA 功能的支持尚未达到这个水平,但最流行的屏幕阅读器正在逐渐实现。您可以通过查看 Powermapper 的WAI-ARIA 屏幕阅读器兼容性文章来了解支持级别。
在本文中,我们不会尝试涵盖所有 WAI-ARIA 功能及其确切的支持细节。相反,我们将涵盖您需要了解的最关键的 WAI-ARIA 功能;如果我们没有提及任何支持细节,您可以假定该功能得到良好支持。我们将明确提及任何例外情况。
注意:一些 JavaScript 库支持 WAI-ARIA,这意味着当它们生成复杂的表单控件等 UI 功能时,它们会添加 ARIA 属性以提高这些功能的可访问性。如果您正在寻找用于快速 UI 开发的第三方 JavaScript 解决方案,则在做出选择时,您绝对应该将 UI 小部件的可访问性视为一个重要因素。很好的例子是 jQuery UI(参见关于 jQuery UI:深度可访问性支持)、ExtJS 和Dojo/Dijit。
何时应该使用 WAI-ARIA?
我们之前讨论了一些促使 WAI-ARIA 创建的问题,但本质上,WAI-ARIA 在四个主要领域很有用
- 路标/地标
-
ARIA 的
role
属性值可以充当地标,它们可以复制 HTML 元素的语义(例如<nav>
),或者超越 HTML 语义,为不同的功能区域提供路标,例如search
、tablist
、tab
、listbox
等。 - 动态内容更新
-
屏幕阅读器通常难以报告不断变化的内容;使用 ARIA,我们可以使用
aria-live
在内容区域动态更新时通知屏幕阅读器用户:例如,通过 JavaScript 在页面中从服务器获取新内容并更新 DOM。 - 增强键盘可访问性
-
有一些内置的 HTML 元素具有原生的键盘可访问性;当其他元素与 JavaScript 一起用于模拟类似交互时,键盘可访问性和屏幕阅读器报告会因此受到影响。在不可避免的情况下,WAI-ARIA 提供了一种方法,允许其他元素接收焦点(使用
tabindex
)。 - 非语义控件的可访问性
-
当一系列嵌套的
<div>
与 CSS/JavaScript 一起用于创建复杂的 UI 功能,或者原生控件通过 JavaScript 大幅增强/改变时,可访问性可能会受到影响——如果没有语义或其他线索,屏幕阅读器用户将难以弄清楚该功能的作用。在这种情况下,ARIA 可以通过结合使用button
、listbox
或tablist
等角色,以及aria-required
或aria-posinset
等属性来提供所需的功能线索。
在下一节中,我们将更详细地探讨前面描述的四个主要领域,并附带示例。在继续之前,您应该设置一个屏幕阅读器测试环境,以便您可以边学边测试一些示例。有关更多信息,请参阅我们关于测试屏幕阅读器的部分。
您只应在需要时才使用 WAI-ARIA!
使用正确的 HTML 元素会隐式地为您提供所需的角色,并且您应该始终使用原生 HTML 功能来提供屏幕阅读器所需的语义,以便告知其用户正在发生什么。有时这不可能,要么是因为您对代码的控制有限,要么是因为您正在创建一些复杂且没有简单 HTML 元素来实现的内容。在这种情况下,WAI-ARIA 可能是一个有价值的可访问性增强工具。
但再次强调,仅在必要时才使用它!
此外,请尽量确保您使用各种真实用户测试您的网站——非残障人士、使用屏幕阅读器的人、使用键盘导航的人等。他们将比您更好地了解网站的运作情况。
路标/地标
WAI-ARIA 为浏览器添加了 role
属性,允许您在需要时为网站上的元素添加额外的语义价值。第一个主要用途是为屏幕阅读器提供信息,以便其用户可以找到常见的页面元素。此示例具有以下结构
<header>
<h1>Header</h1>
<!-- Even is it's not mandatory, it's common practice to put the main navigation menu within the main header -->
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Team</a></li>
<li><a href="#">Projects</a></li>
<li><a href="#">Contact</a></li>
</ul>
<!-- A Search form is another common non-linear way to navigate through a website. -->
<form>
<input type="search" name="q" placeholder="Search query" />
<input type="submit" value="Go!" />
</form>
</nav>
</header>
<!-- Here is our page's main content -->
<main>
<!-- It contains an article -->
<article>
<h2>Article heading</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Donec a diam
lectus. Set sit amet ipsum mauris. Maecenas congue ligula as quam viverra
nec consectetur ant hendrerit. Donec et mollis dolor. Praesent et diam
eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue
enim, ut porta lorem lacinia consectetur.
</p>
<h3>subsection</h3>
<p>
Donec ut librero sed accu vehicula ultricies a non tortor. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Aenean ut gravida lorem. Ut
turpis felis, pulvinar a semper sed, adipiscing id dolor.
</p>
</article>
<!-- the aside content can also be nested within the main content -->
<aside>
<h2>Related</h2>
<ul>
<li><a href="#">Oh I do like to be beside the seaside</a></li>
<li><a href="#">Oh I do like to be beside the sea</a></li>
<li><a href="#">Although in the North of England</a></li>
<li><a href="#">It never stops raining</a></li>
<li><a href="#">Oh well...</a></li>
</ul>
</aside>
</main>
<!-- And here is our main footer that is used across all the pages of our website -->
<footer>
<p>©Copyright 2050 by nobody. All rights reversed.</p>
</footer>
如果您尝试在现代浏览器中使用屏幕阅读器测试该示例,您将已经获得一些有用的信息。例如,VoiceOver 会为您提供以下信息
- 在
<header>
元素上——“横幅,2 项”(它包含一个标题和<nav>
)。 - 在
<nav>
元素上——“导航,2 项”(它包含一个列表和一个表单)。 - 在
<main>
元素上——“主要,2 项”(它包含一篇文章和一个侧边栏)。 - 在
<aside>
元素上——“补充,2 项”(它包含一个标题和一个列表)。 - 在搜索表单输入上——“搜索查询,文本开头插入”。
- 在
<footer>
元素上——“页脚,1 项”。
如果您转到 VoiceOver 的地标菜单(使用 VoiceOver 键 + U 访问,然后使用光标键循环浏览菜单选项),您会看到大多数元素都很好地列出,以便可以快速访问。
然而,我们可以在这里做得更好。搜索表单是一个非常重要的地标,人们会想要找到它,但它没有列在地标菜单中,也没有被视为除实际输入被识别为搜索输入(<input type="search">
)之外的显著地标。
要将表单标记为地标,您可以将其包装在 <search>
元素中,或者为其提供 ARIA role="search"
。一般规则是,尽可能使用 HTML 语义,仅在没有 HTML 等效项时才使用 ARIA。
<header>
<h1>Header</h1>
<!-- Even is it's not mandatory, it's common practice to put the main navigation menu within the main header -->
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Our team</a></li>
<li><a href="#">Projects</a></li>
<li><a href="#">Contact</a></li>
</ul>
<!-- A Search form is another common non-linear way to navigate through a website. -->
<search>
<form>
<input
type="search"
name="q"
placeholder="Search query"
aria-label="Search through site content" />
<input type="submit" value="Go!" />
</form>
</search>
</nav>
</header>
<!-- Here is our page's main content -->
<main>
<!-- It contains an article -->
<article>
<h2>Article heading</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Donec a diam
lectus. Set sit amet ipsum mauris. Maecenas congue ligula as quam viverra
nec consectetur ant hendrerit. Donec et mollis dolor. Praesent et diam
eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue
enim, ut porta lorem lacinia consectetur.
</p>
<h3>subsection</h3>
<p>
Donec ut librero sed accu vehicula ultricies a non tortor. Lorem ipsum
dolor sit amet, consectetur adipisicing elit. Aenean ut gravida lorem. Ut
turpis felis, pulvinar a semper sed, adipiscing id dolor.
</p>
<p>
Pelientesque auctor nisi id magna consequat sagittis. Curabitur dapibus,
enim sit amet elit pharetra tincidunt feugiat nist imperdiet. Ut convallis
libero in urna ultrices accumsan. Donec sed odio eros.
</p>
</article>
<!-- the aside content can also be nested within the main content -->
<aside>
<h2>Related</h2>
<ul>
<li><a href="#">Oh I do like to be beside the seaside</a></li>
<li><a href="#">Oh I do like to be beside the sea</a></li>
<li><a href="#">Although in the North of England</a></li>
<li><a href="#">It never stops raining</a></li>
<li><a href="#">Oh well...</a></li>
</ul>
</aside>
</main>
<!-- And here is our main footer that is used across all the pages of our website -->
<footer>
<p>©Copyright 2050 by nobody. All rights reversed.</p>
</footer>
最重要的是,我们使用了语义化 HTML,它赋予了页面结构意义和角色,而没有在我们的 HTML 结构中添加不必要的 role
属性,其结构如下
<header>
<h1>…</h1>
<nav>
<ul>
…
</ul>
<search>
<form>
<!-- search form -->
</form>
</search>
</nav>
</header>
<main>
<article>…</article>
<aside>…</aside>
</main>
<footer>…</footer>
在此示例中,我们还为您提供了一个额外功能——<input>
元素被赋予了属性 aria-label
,它为其提供了一个描述性标签,即使我们没有包含 <label>
元素,屏幕阅读器也会将其读出。在这些情况下,这非常有用——像这样的搜索表单是一个非常常见、易于识别的功能,添加可视标签会破坏页面设计。
<input
type="search"
name="q"
placeholder="Search query"
aria-label="Search through site content" />
现在,如果我们使用 VoiceOver 查看此示例,我们会得到一些改进
- 搜索表单在浏览页面和地标菜单中都被单独列出。
- 当表单输入被高亮显示时,会读出
aria-label
属性中包含的标签文本。
如果您需要支持 IE8 等旧版浏览器;为此目的包含 ARIA 角色是值得的。如果您的网站由于某种原因仅使用 <div>
构建,那么您绝对应该包含 ARIA 角色以提供这些急需的语义!
您将在下面看到更多关于这些语义和 ARIA 属性/属性的强大功能,特别是在非语义控件的可访问性部分。不过现在,让我们看看 ARIA 如何帮助进行动态内容更新。
动态内容更新
加载到 DOM 中的内容可以使用屏幕阅读器轻松访问,从文本内容到附加到图像的替代文本。因此,具有大量文本内容的传统静态网站很容易让有视力障碍的人访问。
问题是现代 Web 应用程序通常不只是静态文本——它们通常通过从服务器获取新内容(在此示例中,我们使用静态引用数组)和更新 DOM 来更新页面的一部分。这些有时被称为实时区域。
让我们看一个示例——一个随机名言生成器
<section>
<h1>Random quote generator</h1>
<button>Start giving me quotes</button>
<blockquote>
<p></p>
</blockquote>
</section>
let quotes = [
{
quote:
"Every child is an artist. The problem is how to remain an artist once he grows up.",
author: "Pablo Picasso",
},
{
quote:
"You can never cross the ocean until you have the courage to lose sight of the shore.",
author: "Christopher Columbus",
},
{
quote:
"I love deadlines. I love the whooshing noise they make as they go by.",
author: "Douglas Adams",
},
];
const quotePara = document.querySelector("section p");
const btn = document.querySelector("button");
btn.addEventListener("click", () => {
function showQuote() {
let random = Math.floor(Math.random() * quotes.length);
quotePara.textContent = `${quotes[random].quote} -- ${quotes[random].author}`;
}
showQuote();
btn.disabled = true;
window.setInterval(showQuote, 5000);
});
这工作正常,但不利于可访问性——屏幕阅读器无法检测到内容更新,因此其用户将不知道发生了什么。这是一个相当微不足道的示例,但想象一下,如果您正在创建一个具有大量不断更新内容的复杂 UI,例如聊天室、策略游戏 UI 或实时更新的购物车显示——如果没有某种方式提醒用户更新,将无法有效使用该应用程序。
WAI-ARIA 幸运地提供了一种有用的机制来提供这些警报——aria-live
属性。将此属性应用于元素会导致屏幕阅读器读出更新的内容。内容读出的紧急程度取决于属性值
在这里,我们更新 <blockquote>
开标签,如下所示
<blockquote aria-live="assertive">…</blockquote>
这将导致屏幕阅读器在内容更新时读出内容:尝试测试更新的实时版本
注意:还有一些其他与 aria-live
相关的 ARIA 属性也值得了解
aria-atomic
属性,当设置为true
时,告诉屏幕阅读器将整个元素内容作为一个原子单元读出,而不仅仅是更新的部分。当只有部分内容正在更新时,这很有用,但您也希望每次内容更改时都读出标题,以提醒用户其内容。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 属性,该错误消息框在您尝试提交表单时显示任何验证错误
<div class="errors" role="alert" aria-relevant="all">
<ul></ul>
</div>
role="alert"
自动将其应用的元素转换为实时区域,因此对其的更改会被读出;它还在语义上将其标识为警报消息(重要的时间/上下文敏感信息),并且代表了一种更好、更易于访问的方式向用户传递警报(像alert()
调用这样的模态对话框存在许多可访问性问题;请参阅 WebAIM 的弹出窗口)。aria-relevant
值为all
指示屏幕阅读器在对错误列表进行任何更改时(即添加或删除错误时)读出错误列表的内容。这很有用,因为用户会想知道还剩下哪些错误,而不仅仅是列表中添加或删除了什么。
我们可以进一步使用 ARIA,提供更多验证帮助。例如,如何指示字段是否必填,以及年龄范围应该是多少?
-
此时,复制我们的
form-validation.html
和validation.js
文件,并将它们保存在本地目录中。 -
在文本编辑器中打开它们,并查看代码是如何工作的。
-
首先,在开头的
<form>
标签上方添加一个段落,如下所示,并在两个表单<label>
标签上标记一个星号。这通常是我们为有视力用户标记必填字段的方式。html<p>Fields marked with an asterisk (*) are required.</p>
-
这在视觉上是合理的,但对于屏幕阅读器用户来说并不容易理解。幸运的是,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" />
-
如果您现在保存示例并使用屏幕阅读器进行测试,您应该会听到类似“输入您的姓名星号,必填,编辑文本”的声音。
-
如果我们为屏幕阅读器用户和有视力用户提供年龄值应该是什么范围的概念,那也可能很有用。这通常以工具提示或占位符的形式呈现在表单字段中。WAI-ARIA 确实包含
aria-valuemin
和aria-valuemax
属性来指定最小值和最大值,并且屏幕阅读器支持原生min
和max
属性。另一个得到良好支持的功能是 HTMLplaceholder
属性,它可以在未输入值时在输入框中显示一条消息,并由一些屏幕阅读器读出。像这样更新您的数字输入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-label
和 aria-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
演示中,有一个复选框,当选中时,它会启用另一个表单输入以允许输入更多信息。我们设置了一个隐藏的实时区域
<p class="hidden-alert" aria-live="assertive"></p>
它使用绝对定位从视图中隐藏。当选中/取消选中此复选框时,我们会更新隐藏实时区域内的文本,以告知屏幕阅读器用户选中此复选框的结果是什么,并更新 aria-disabled
状态和一些视觉指示器。
function toggleMusician(bool) {
const instrument = formItems[formItems.length - 1];
if (bool) {
instrument.input.disabled = false;
instrument.label.style.color = "black";
instrument.input.setAttribute("aria-disabled", "false");
hiddenAlert.textContent =
"Instruments played field now enabled; use it to tell us what you play.";
} else {
instrument.input.disabled = true;
instrument.label.style.color = "#999999";
instrument.input.setAttribute("aria-disabled", "true");
instrument.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"
,例如
<div data-message="This is from the first button" tabindex="0" role="button">
Click me!
</div>
现在,当您使用屏幕阅读器尝试此操作时,您将听到按钮以“点击我!按钮”之类的短语报告。虽然这要好得多,但您仍然必须添加用户期望的所有原生按钮功能,例如处理 enter 和点击事件,如button
角色文档中所述。
引导用户通过复杂的小部件
还有许多其他角色可以将非语义元素结构标识为超出标准 HTML 范围的常见 UI 功能,例如 combobox
、slider
、tabpanel
、tree
。您可以在 Deque 大学代码库中看到几个有用的示例,以了解如何使此类控件具有可访问性。
您还可以在我们的 WAI-ARIA 角色文档中找到几个实时示例。例如,请参阅我们的 ARIA: tab 角色示例,其中解释了如何实现可访问的选项卡式界面。
总结
本文绝没有涵盖 WAI-ARIA 中所有可用的内容,但它应该为您提供了足够的信息,让您了解如何使用它,并了解您将遇到的一些最常见的需要它的模式。
在下一篇文章中,我们将为您提供一些测试,您可以使用它们来检查您对所有这些信息的理解和掌握程度。
另见
- Aria 状态和属性:所有
aria-*
属性 - WAI-ARIA 角色:ARIA 角色的类别和 MDN 上涵盖的角色
- W3C 上的 HTML 中的 ARIA:一个规范,定义了每个 HTML 功能,浏览器对其隐式应用的(ARIA)可访问性语义以及如果需要额外语义,您可以设置的 WAI-ARIA 功能
- Deque 大学代码库:一个包含非常有用的实用示例的库,展示了如何使用 WAI-ARIA 功能使复杂 UI 控件具有可访问性
- W3C 上的 WAI-ARIA 创作实践:W3C 的一份非常详细的设计模式,解释了如何实现不同类型的复杂 UI 控件,同时使用 WAI-ARIA 功能使它们具有可访问性