参考文档:
Tencent Document
W3C Document
MDN Document
什么是无障碍?
无障碍是一种让尽可能多的用户可以使用你的网站的做法。传统上我们认为这只与残疾人士有关,但提升网站的无障碍也可以让其他用户群体受益。我们都是不同的,但我们都是人,因此享有同等的人权。
Accessible Rich Internet Applications (WAI-ARIA) 1.1(无障碍丰富互联网应用(WAI-ARIA)1.1)
WAI-ARIA是 W3C 编写的规范,定义了一组可用于其他元素的 HTML 特性——角色、属性和状态,用于提供额外的语义以及改善缺乏的可访问性。因此它能让更多的信息从浏览器暴露给 accessibility APIs (无障碍 API),这也是读屏软件这一类软件的信息源。
注意事项
Menu
- Hover和Focus时 应该保持相同的样式
- 子菜单(submenu),也称为弹出菜单(popup menu),具有
menu
角色。 - 当打开一个
menu
,或当menubar
获得焦点, 键盘焦点会置于第一项上。 如 § 6.6 组件内的键盘导航中所述,所有菜单项都是可聚焦的。 - Enter:
- 当焦点在一个
menuitem
元素上时,若其包含子菜单则打开子菜单,并将焦点置于该子菜单中的第一项上。 - 否则,激活当前菜单项并关闭菜单。
- Space:
- (可选): 当焦点在
menuitemcheckbox
元素上,在不关闭菜单的情况下切换其选中/未选中状态。 - (可选): 当焦点在 menuitemradio 元素上且未选中时,在不关闭菜单的情况下,选中当前 menuitemradio 元素并取消选中同组中任何已选中的 menuitemradio 元素。
- (可选): 当焦点在 menuitem 元素上并包含一个子菜单时,则打开子菜单并将焦点置于该子菜单中的第一项上。
- (可选): 当焦点在 menuitem 元素上且不包含子菜单时,则激活此菜单项并关闭菜单。
Common
- 为了让屏幕阅读器用户容易感知和理解,请避免使用非常长的选项名称。阅读选项时,选项的整个名称会作为单个语音单元朗读。如果单次按键操作会朗读大量信息,用户将难以理解。长名称通过增加朗读中断来抑制信息的感知,因为用户通常不得不重新朗读整个选项。而且,如果用户不理解屏幕阅读器说了什么,他们很难在列表框 widget 中实现按字、词、短语朗读。
- 如果选项集中每个选项名称都以使用相同的单词或短语开头,也会显著降低键盘和屏幕阅读器用户的可用性。对屏幕阅读器用户来说,滚动列表找到特定选项是非常费时的,因为他们必须在听到每个选项的差异之前重复听到某个单词或短语。例如,有一个选择城市的列表框,其选项的每个城市名称前面都有国家名称,如果每个国家都列出了很多城市,屏幕阅读器用户不得不在听完国家名称之后才听到城市名称。这种情况最好是有两个列表框,一个用于选择国家,一个用于选择城市。
常用属性
- aria-label 需要读的文本内容
- aria-disabled 该状态表示该元素可感知但已禁用,因此它不可编辑或不可操作。
- aria-selected 该状态表示该元素已选中
- aria-describedby 和id建立关系,和aria-labelledby差不多,描述冗长内容
- aria-labelledby 和id建立关系,直接读id元素的child内容,不会按照默认情况下的读所有子元素的child和aria-label内容,描述简介内容
- tabIndex
- -1 表示该元素无法通过顺序键盘导航访问,但可以使用 JavaScript 或通过鼠标单击以可视方式聚焦。使用 JavaScript 创建可访问的小部件最有用。
- 0 意味着在任何正的 tabindex 值之后,该元素应该在顺序键盘导航中可聚焦,并且其顺序由文档的源顺序定义。
- aria-busy true/false 指示内容正在加载
interactive elements(role)
- button
- link
- menuitem
- searchbox
- textbox
常用键盘操作
判断Shift键是否摁下? event.shiftKey is true
- Escape
- ArrowUp
- ArrowDown
- ArrowLeft
- ArrowRight
- Tab
- Shift + Tab
- Space
- Enter
避免使用
visibility:hidden
或 display:none
,因为它们会隐藏屏幕阅读器中的内容。当然,除非你希望从屏幕阅读器中隐藏此内容,这是有充分理由的。
经验
focus到元素上,但是不读内容
<span
ref={textRef}
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
tabIndex="0"
>
<span aria-hidden>{type}</span>
</span>