当我开始学习 ARIA 时,希望有人告诉我的事
可访问富互联网应用(ARIA)是处理 Web 可访问性时不可避免的技术。不过,每个人在某个阶段都是第一次学习 ARIA。
如果你之前没接触过 ARIA,太好了!这是一个学习新知识的机会。如果你已经听说过 ARIA,本文可能会帮助你更好地理解它,甚至教你一些新东西!
这些都是我希望在我开始 Web 可访问性之旅时有人告诉我的事情。本文将:
- 提供处理 ARIA 作为一种概念的心态;
- 揭穿一些常见的误解;
- 提供一些指导思路,帮助你更好地理解和使用它。
我希望通过这样做,使 Web 设计和开发中一个经常被忽视但至关重要的角落更容易接近。
本文不是什么
本文不是如何使用 ARIA 构建可访问网站和 Web 应用的配方书,也不是如何修复不可访问体验的指南。许多可访问性工作高度依赖于上下文。我不知道你的项目或组织的具体需求,因此在这里提供建议可能弊大于利。
相反,请将本文视为“行前须知”指南。我希望为你提供一个处理 ARIA 的良好心态,并突出你在旅程中需要注意的事项。那么,让我们开始吧!
那么,什么是 ARIA?
ARIA 是在没有更适合传达交互性、目的和状态的原生 HTML 元素或属性时所求助的技术。
将其视为一种你撒入标记中以增强事物的香料。
将 ARIA 添加到 HTML 标记中是为屏幕阅读器和语音控制软件提供网站或 Web 应用的额外信息的一种方式。
- 交互性 意味着内容可以被激活或操作。例如,导航到链接的目标。
- 目的 意味着某物的用途。例如,用于收集某人姓名的文本输入。
- 状态 意味着内容当前所处的状态,由状态、属性和值控制。例如,可以展开或折叠的手风琴面板。
以下是一个说明:
(大型预览)
HTML 的按钮元素的存在将指示辅助技术将其报告为按钮,让某人知道它可以被激活以执行预定义的操作。
文本字符串“Mute”的存在将由辅助技术报告,以提示该按钮的用途。
aria-pressed="true"
的存在意味着某人或某物之前激活了该按钮,并且它现在处于“按下”状态,持续其操作。
这种整体模式将让使用辅助技术的人知道:
- 某物是否可交互,
- 它执行哪种交互行为,以及
- 它的当前状态。
ARIA 的历史
ARIA 已经存在很长时间了,第一个版本发布于 2006 年 9 月 26 日。
(大型预览)
ARIA 的创建是为了在 HTML 的局限性与使辅助技术理解交互体验的需求之间架起桥梁。
“ARIA 的最新版本是 2023 年 6 月 6 日发布的 1.2 版。1.3 版预计很快发布,你可以在 Craig Abbott 的这篇优秀文章中阅读更多关于它的信息。
你可能也看到它被称为 WAI-ARIA,其中 WAI 代表“Web 可访问性倡议”。WAI 是 W3C 的一部分,该组织为 Web 制定标准。也就是说,我认识的大多数可访问性从业者在书面和口头交流中称其为“ARIA”,并省略“WAI-”部分。
ARIA 的精神反映了其创建时代的特征
原因很简单:过去的 Web 远不如现在成熟。2006 年最流行的操作系统是 Windows XP。iPhone 尚未存在;它是在一年后发布的。
从非常高的层面来看,ARIA 是这个时期操作系统交互范式的快照。这是因为 ARIA 重新创建了它们。
图片来源:Microsoft Windows XP Wiki。(大型预览)
心态
具有可点击、可滑动和可拖动表面等功能的智能手机远不那么普遍。单页应用“Web 应用”体验也很罕见,基于 Ajax 的方法最为流行。这意味着我们必须使用 2006 年的技术构建今天的体验。在某种程度上,这是一件好事。它迫使我们接受新颖的体验并审视它们。
无法分解为更小、更集中的部分并映射到 ARIA 模式的交互很可能不可访问。这是因为它们将无法由辅助技术操作或在较旧或较不流行的设备上运行。
我可能有偏见,但我认为这些无法转换的新颖交互也作为一个警告,表明普通受众会发现它们令人困惑,因此无法使用。考虑到互联网服务于:
- 未知数量的人,
- 使用未知数量的设备,
- 每个设备都有未知数量的个人定制,
- 拥有自己独特的需求和环境,并且
- 有未知的动机因素。
这一信念是重要的。
交互期望
当代对基于键盘的 Web 内容交互的期望——复选框、单选按钮、模态框、手风琴等——源自 Windows XP 及其前身操作系统。这些交互模型作为使用辅助技术的老年人的肌肉记忆延续下来。依赖辅助技术的年轻人也学习这些事实上的标准,从而延续了这一循环。
这对你意味着什么?使用键盘与你的网站或 Web 应用交互的人很可能会首先尝试这些基于 Windows 操作系统的键盘快捷键。这意味着诸如按下:
- Enter 键导航到链接的目标,
- 空格键激活按钮,
- Home 和 End 键跳转到项目列表的开头或结尾,等等。
它也是一份活文档
这并不是说 ARIA 停滞不前。它不断被改进,有新的添加、删除和澄清。记住,它现在处于 1.2 版,1.3 版即将到来。
并行地,HTML 作为一种语言也反映了这种演变。元素最初是为了支持面向文档的 Web 而创建的,并逐渐演变为支持更动态、类似应用的体验。很棒的一点是,这一切都是公开进行的,如果你有动力,可以为之做出贡献。
ARIA 有使用规则
ARIA 的文档中包含五条规则,以帮助指导你如何处理它:
- 尽可能使用原生元素。
例如,使用锚元素(
<a>
)作为链接,而不是带有点击处理程序和链接角色的 div。 - 尽可能不要调整原生元素的语义。 例如,尝试使用标题元素作为标签,而不是将标题包装在语义中性的 div 中。
- 任何交互元素都必须可键盘操作。 如果你不能用键盘使用它,它就不可访问。句号。
- 不要在可聚焦元素上使用
role="presentation"
或aria-hidden="true"
。 这会使意图交互的东西无法被辅助技术使用。 - 交互元素必须被命名。 例如,对按钮元素使用文本字符串“Print”。
遵守这五条规则将对你大有帮助。以下提供更多上下文以提供更多支持。
ARIA 有一个分类法
ARIA 有一个结构化的语法,它以角色以及状态和属性为中心。
角色
角色 是辅助技术读取并宣布的内容。许多人将其简称为语义。HTML 元素具有隐含角色,这就是为什么锚元素会被屏幕阅读器宣布为链接,而无需额外工作。
(大型预览)
如果用例需要,隐含角色几乎总是更好使用。回想一下 ARIA 的第一条规则。这通常是数字可访问性从业者在说“只需使用语义 HTML”时所指的。
偏爱隐含角色有很多原因。主要考虑是更好地保证在未知数量的操作系统、浏览器和辅助技术组合中的支持。
角色有类别,每个类别都有自己的目的。抽象角色类别值得注意,因为它是一个组织超级类别,不打算由作者使用:
抽象角色用于本体论。作者不得在内容中使用抽象角色。
|
|
此外,同样地,你只能在某些东西上声明 ARIA,你只能将一些 ARIA 声明为其他 ARIA 声明的子项。例如,listitem
角色要求其父元素存在 list
角色。
那么,确定角色是否需要父声明的最佳方法是什么?答案是查看官方定义。
状态和属性
状态和属性 是 ARIA 整体分类法的另外两个主要部分。
隐含角色由语义 HTML 提供,显式角色由 ARIA 提供。两者都描述了元素是什么。状态以辅助技术可以理解的方式描述该元素的特征。这是通过属性声明及其伴随值完成的。
(大型预览)
ARIA 状态可以快速或缓慢地改变,无论是由于人类交互还是应用状态。当状态由于人类交互而改变时,它被认为是“非托管状态”。在这里,开发人员必须提供底层的 JavaScript 逻辑来控制交互。
当状态由于应用(例如,操作系统、Web 浏览器等)而改变时,这被认为是“托管状态”。在这里,应用自动提供底层逻辑。
如何声明 ARIA
将 ARIA 视为 HTML 属性的扩展,一套名称/值对。有些值是预定义的,而其他值是由作者提供的:
(大型预览)
对于上图中的示例,aria-live
的 polite
值是三个预定义值(off
、polite
和 assertive
)之一。对于 aria-label
,“Save”是作者手动提供的文本字符串。
你在 HTML 元素上声明 ARIA 的方式与声明其他属性的方式相同:
|
|
其他使用说明:
- 你可以在一个 HTML 元素上放置多个 ARIA 声明。
- 在 HTML 元素上声明 ARIA 时的顺序无关紧要。
- 对元素可以放置的 ARIA 声明数量没有限制。注意,你添加的越多,引入的复杂性就越大,而更多的复杂性意味着事情可能破坏或无法按预期运行的机会更大。
- 你可以在 HTML 元素上声明 ARIA,也可以有其他非 ARIA 声明,例如
class
或id
。这里的声明顺序也无关紧要。
可能也有帮助的是,知道布尔属性在 ARIA 中与在 HTML 中处理方式略有不同。Hidde de Vries 在他的文章“HTML 和 ARIA 中的布尔属性:有什么区别?”中写了这一点。
没有多少 ARIA 是“硬编码”的
在这种上下文中,“硬编码”意味着直接将静态属性或值声明写入组件、视图或页面。
许多 ARIA 设计为基于应用状态或作为某人操作的响应动态应用或条件修改。例如,显示和隐藏披露模式:
- ARIA 的
aria-expanded
属性在false
和true
之间切换,以传达披露是处于展开还是折叠状态。 - HTML 的
hidden
属性条件性地移除或添加,以显示或隐藏披露的完整内容区域。
|
|
你在 Web 上遇到的硬编码 ARIA 声明的常见示例是使按钮内的 SVG 图标具有装饰性:
|
|
在这里,字符串“Save”是某人理解按钮在激活时将做什么所必需的。伴随的图标在视觉上帮助理解,但被认为是冗余的,因此具有装饰性。
在已经隐含使用该角色的东西上声明 ARIA 角色不会使其“额外”可访问
如果你使用语义 HTML,隐含角色就是你所需要的。通过 ARIA 显式声明其角色不会带来任何额外优势。
|
|
你可能偶尔会在 HTML 分区元素上遇到这些冗余声明,例如 <main role="main">
或 <footer role="contentinfo">
。这不再需要,你可以只使用 <main>
或 <footer>
元素。
原因是历史性的。这些声明是为了支持原因而完成的,因为它是一种权宜之计,用于需要更新以支持这些当时新的 HTML 元素的辅助技术。
当代辅助技术不需要这些冗余声明。以我们不再需要为 CSS border-radius
属性使用供应商前缀的方式思考。
注意:此指导有一个例外。在某些情况下,某些复杂和复杂的标记模式无法按预期用于辅助技术。在这些情况下,我们希望将隐式角色硬编码为显式 ARIA 以确保其工作。此辅助技术支持问题将在本文后面更详细地介绍。
你不需要说控件是什么;那是角色的用途
屏幕阅读器会宣布隐式和显式角色。你不需要为交互元素的文本字符串或 aria-label
等内容包含该部分。
|
|
如果我们为我们的保存按钮使用字符串值“Save button”,屏幕阅读器会宣布类似“Save button, button”的内容。那是冗余和令人困惑的。
ARIA 角色有非常具体的含义
我们有时 colloquially 将网站和 Web 应用导航称为菜单,尤其是如果它是电子商务风格的巨型菜单。
在 ARIA 中,菜单意味着非常具体的东西。不要考虑全局或页面内导航等。在这种上下文中,将菜单视为当你单击应用程序菜单栏上的“编辑”菜单按钮时出现的内容。
Notepad,Windows 11。(大型预览)
因为其名称乍一看似乎合适而错误地使用角色,会对没有视觉 UI 上下文的人造成混淆。他们的期望将随着角色的宣布而设定,然后在它不按预期方式行动时被颠覆。
想象一下,如果你单击一个链接,它不是将你带到另一个网页,而是将完全不相关的东西发送到你的打印机。有点类似那样。
声明 role="menu"
是错误应用角色的常见示例,但还有其他。知道角色用途的最佳方法?直接查看来源并阅读它。
某些角色被禁止具有可访问名称
这些角色是 caption
、code
、deletion
、emphasis
、generic
、insertion
、paragraph
、presentation
、strong
、subscript
和 superscript
。
这意味着你可以尝试为这些元素之一提供可访问名称——例如通过 aria-label
——但它不会工作,因为它被 ARIA 语法规则禁止。
|
|
对于这些示例,回想一下角色是隐含的,源自声明的 HTML 元素。
注意,有时浏览器会无论如何尝试并覆盖作者指定的字符串值。这种覆盖对所有相关方来说都是一个令人困惑的行为,这导致了规则的首先建立。
你不能编造 ARIA 并期望它工作
我见过一些开发人员猜测添加 CSS 类,例如 .background-red
或 .text-white
,到他们的标记中,并在设计视觉上正确更新时得到奖励。
这工作的原因是有人之前将这些类添加到项目中。对于 ARIA,添加我们可以使用的内容的人是可访问富互联网应用工作组。这意味着每个新版本的 ARIA 都有一个预定义的属性和值集。然后辅助技术被更新以解析这些属性和值,尽管这并不总是保证。
声明不属于该预定义集的 ARIA 意味着辅助技术不会知道它是什么,因此不会宣布它。
|
|
ARIA 静默失败
这涉及到前一部分,其中 ARIA 不会理解在其有限词汇表之外所说的单词。
对于格式错误的 ARIA,没有控制台错误。也没有警报对话框、蜂鸣声或闪烁灯用于你的操作系统、浏览器或辅助技术。这一事实是为什么用实际辅助技术测试如此重要的另一个原因。
你也不必成为专家。如果你将某些东西设置为宣布为特定状态,而辅助技术在其默认配置中不宣布该状态,那么你的代码很可能需要更新。
ARIA 仅将某物的存在暴露给辅助技术
将 ARIA 应用于某物不会自动“解锁”功能。它只向辅助技术发送关于交互内容应如何行为的提示。
对于像屏幕阅读器这样的辅助技术,该提示可能是关于如何宣布某物。对于像可刷新盲文显示器这样的辅助技术,它可能是关于如何升高和降低其引脚。例如,在 div
元素上声明 role="button"
不会自动使其可点击。你仍然需要:
- 在 JavaScript 中定位
div
元素, - 将其绑定到点击事件,
- 编写点击时执行的交互逻辑,然后
- 容纳所有其他预期行为。
这一切让我想知道为什么你不能首先节省一些工作并使用按钮元素,但那是另一天的另一个故事。
此外,通过 ARIA 调整元素的角色不会修改元素的本地功能。例如,你可以在 div
元素上声明 role="image"
。然而,尝试在 div
上声明 alt
或 src
属性不会工作。这是因为 alt
和 src
不是 div