Web 开发者的无障碍功能

改进无障碍功能使您的网站对所有人更易于使用。

构建对所有人包容且无障碍的网站非常重要。您可以针对至少六个关键的残疾领域进行优化:视觉听觉行动认知言语神经。即使您是 Web 无障碍功能的全新手,许多工具和资源也可以在此处提供帮助。

超过 10 亿人患有某种形式的残疾。

为了实现无障碍功能,网站需要在具有不同屏幕尺寸和不同类型输入(如屏幕阅读器)的多种设备上运行。此外,网站应可供最广泛的用户群体使用,包括残疾人士。

以下是您的用户可能遇到的一些残疾

视觉 听觉 行动
  • 低视力
  • 失明
  • 色盲
  • 白内障
  • 阳光眩光
  • 听力障碍
  • 失聪
  • 噪音
  • 耳朵感染
  • 脊髓损伤
  • 灵活性受限
  • 双手被占用
认知 言语 神经
  • 学习障碍
  • 困倦或分心
  • 偏头痛
  • 自闭症
  • 癫痫发作
  • 环境噪音
  • 喉咙痛
  • 言语障碍
  • 无法说话
  • 抑郁症
  • 创伤后应激障碍
  • 躁郁症
  • 焦虑症

视觉问题的范围从无法区分颜色到完全失明。

  • 确保文本内容满足最低对比度阈值
  • 避免仅使用颜色传达信息,并确保所有文本都是可调整大小的。
  • 确保所有用户界面组件都可以与辅助技术(如屏幕阅读器、放大镜和盲文显示器)一起使用。这需要确保对 UI 组件进行标记,以便辅助功能 API 可以通过编程方式确定任何元素的角色状态标题

Screenshot of the Chrome DevTools Inspect Element tooltip.

我个人患有低视力,并且经常发现自己放大网站、其 DevTools 和终端。虽然支持缩放几乎永远不会成为开发人员的首要任务,但它可以为像我这样的用户带来天壤之别。

听力问题意味着用户可能在听到页面发出的声音时遇到问题。

  • 为所有并非严格意义上的文本内容提供文本替代方案
  • 测试您的 UI 组件在没有声音的情况下是否仍然可以正常运行。

Screenshot of the ChromeVox screen reader reading a web page.

行动问题可能包括无法操作鼠标、键盘或触摸屏。

  • 使您的 UI 组件的内容对于任何原本使用鼠标执行的操作,都可以通过键盘在功能上访问
  • 确保页面已针对辅助技术(包括屏幕阅读器、语音控制软件和物理开关控件)正确标记,这些技术倾向于使用相同的 API。

认知问题意味着用户可能需要辅助技术来帮助他们阅读文本,因此务必确保存在文本替代方案。

  • 在使用动画时请注意。避免重复或闪烁的视频和动画,这可能会给某些用户带来问题

    prefers-reduced-motion CSS 媒体查询允许您为喜欢减少动态效果的用户限制动画和自动播放视频

    /*
    If the user expresses a preference for reduced motion, don't use animations on buttons.
    */
    @media (prefers-reduced-motion: reduce) {
      button {
        animation: none;
      }
    }
    
  • 避免基于时间的交互。

这看起来似乎需要涵盖很多方面,但我们将逐步介绍评估然后改进 UI 组件的无障碍功能的过程。

为了获得额外的视觉支持,GOV.UK 无障碍功能团队制作了一系列无障碍功能设计须知和禁忌数字海报,您可以使用它们与您的团队分享最佳实践。

Digital posters showing accessibility dos and don'ts.
六张海报列出了无障碍功能最佳实践。阅读全文

衡量 UI 组件的无障碍功能

在审核页面的 UI 组件的无障碍功能时,请问自己

  • 您是否只能使用键盘来使用 UI 组件?

    组件是否管理焦点并避免焦点陷阱?它是否可以响应适当的键盘事件?

  • 您是否可以使用屏幕阅读器来使用 UI 组件?

    您是否为以视觉方式呈现的任何信息提供了文本替代方案?您是否使用 ARIA 添加了语义信息?

  • 您的 UI 组件是否可以在没有声音的情况下工作?

    关闭扬声器并浏览您的用例。

  • 您的 UI 组件是否可以在没有颜色的情况下工作?

    确保无法看到颜色的人可以使用您的 UI 组件。一个用于模拟色盲的有用工具是名为 Colorblindly 的 Chrome 扩展程序。(尝试所有四种形式的色盲模拟。)您可能还会对 Daltonize 扩展程序感兴趣,它同样有用。

  • 您的 UI 组件是否可以在启用高对比度模式的情况下工作?

    所有现代操作系统都支持高对比度模式。High Contrast 是一个可以在此处提供帮助的 Chrome 扩展程序。

标准化控件(如 <button><select>)在浏览器中内置了无障碍功能。它们可以使用 Tab 键聚焦;它们响应键盘事件(如 EnterSpace 和箭头键);并且它们具有辅助功能工具使用的语义角色、状态和属性。它们的默认样式也应满足列出的无障碍功能要求。

自定义 UI 组件(扩展标准元素(如 <button>)的组件除外)没有任何内置功能,包括无障碍功能,因此您需要提供它。实施无障碍功能时,一个好的起点是将您的组件与类似的标准化元素(或几个标准化元素的组合,具体取决于您的组件的复杂程度)进行比较。

大多数浏览器开发者工具都支持检查页面的辅助功能树。在 Chrome DevTools 中,这在元素面板的 Accessibility 选项卡中可用。

Screenshot of the accessibility tree view in Chrome DevTools.

Firefox 也有一个 Accessibility 面板。

Screenshot of the accessibility tree view in FireFox DevTools.

Safari 在 Elements 面板的 Node 选项卡中公开辅助功能信息。

以下是您在尝试使 UI 组件更具无障碍功能时可以问自己的一系列问题。

改进键盘焦点

理想情况下,确保可以使用键盘访问 UI 组件中的所有功能。在设计用户体验时,请考虑您将如何仅使用键盘来使用元素,并找到一组一致的键盘交互。

首先,确保您为每个组件都有一个合理的焦点目标。例如,像菜单这样的复杂组件可能是页面内的一个焦点目标,但随后应在自身内管理焦点,以便活动菜单项始终获得焦点。

A screenshot of a menu and submenu that requires focus management.
在复杂元素内管理焦点。

使用 tabindex

您可以使用 tabindex 属性为元素和 UI 组件添加键盘焦点。仅使用键盘的用户和辅助技术用户需要能够将键盘焦点放在元素上才能与之交互。

内置交互式元素(如 <button>)是隐式可聚焦的,因此它们不需要 tabindex 属性,除非您需要更改它们在 Tab 键顺序中的位置。

有三种类型的 tabindex

  • tabindex="0" 是最常见的,并将元素放置在自然 Tab 键顺序(由 DOM 顺序定义)中。
  • tabindex 值等于 -1 会导致元素可以通过编程方式聚焦,但不在 Tab 键顺序中。
  • tabindex 值大于 0 会将元素放置在手动 Tab 键顺序中。页面中具有正 tabindex 值的元素都将按数字顺序访问,然后再访问自然 Tab 键顺序中的元素。

在文章 使用 tabindex 中查找 tabindex 的一些用例。

确保焦点始终可见,无论是使用默认的焦点环样式,还是应用可辨别的自定义焦点样式。请记住不要陷住键盘用户,他们应该能够仅使用键盘将焦点从元素上移开。

使用 autofocus

HTML autofocus 属性允许作者指定在页面加载时应自动聚焦特定元素。autofocus 已在所有 Web 表单控件(包括按钮)上得到支持。要自动聚焦您自己的自定义 UI 组件中的元素,请调用 focus() 方法,该方法在所有可以聚焦的 HTML 元素上都受支持(例如,document.querySelector('myButton').focus())。

添加键盘交互

一旦您的 UI 组件可聚焦,请在组件聚焦时通过处理适当的键盘事件来提供良好的键盘交互故事。例如,允许用户使用箭头键选择菜单选项,并使用 SpaceEnter 激活按钮。ARIA 设计模式指南在此处提供了一些指导。

最后,确保您的键盘快捷键是可发现的。一种常见的做法是使用键盘快捷键图例(屏幕文本)来告知用户快捷键的存在。例如,“按 ? 查看键盘快捷键。”或者,可以使用工具提示等提示来告知用户快捷键。

管理焦点的重要性怎么强调都不过分。一个重要的例子是导航抽屉。如果您向页面添加 UI 组件,则需要将焦点定向到其中的元素;否则,用户可能必须通过整个页面进行 Tab 键操作才能到达那里。这可能是一种令人沮丧的体验,因此请务必测试页面中所有可通过键盘导航的组件的焦点。

WalkMe state toggle test.
// Example for expanding and collapsing a category with the Space key
const category = await page.$(`.category`);

// verify tabIndex, role and focus
expect(await page.evaluate(elem => elem.getAttribute(`role`), category)).toEqual(`button`);
expect(await page.evaluate(elem => elem.getAttribute(`tabindex`), category)).toEqual(`0`);
expect(await page.evaluate(elem => window.document.activeElement === elem, category)).toEqual(true);

// verify aria-expanded = false
expect(await page.evaluate(elem => elem.getAttribute(`aria-expanded`), category)).toEqual(`false`);

// toggle category by pressing Space
await page.keyboard.press('Space');

// verify aria-expanded = true
expect(await page.evaluate(elem => elem.getAttribute(`aria-expanded`), category)).toEqual(`true`);

确保屏幕阅读器成功使用

大约 1% 到 2% 的人使用屏幕阅读器。您是否可以使用屏幕阅读器和键盘单独理解所有重要信息并与组件交互?

以下问题应有助于您解决屏幕阅读器的无障碍功能。

所有组件和图像是否都具有有意义的文本替代方案?

无论以视觉方式传达交互式组件的名称还是用途的信息,都要提供可访问的文本替代方案。

例如,如果您的 <fancy-menu> UI 组件仅显示齿轮图标来指示它是设置菜单,则它需要可访问的文本替代方案,例如“设置”,以传达相同的信息。根据上下文,您可以使用 alt 属性、aria-label 属性、aria-labelledby 属性或 Shadow DOM 中的纯文本来提供文本替代方案。您可以在 WebAIM 快速参考中找到一般技术提示。

任何显示图像的 UI 组件都应提供一种机制来为该图像提供替代文本,类似于 alt 属性。

您的组件是否提供语义信息?

辅助技术传达语义信息,否则这些信息会通过视觉提示(如格式、光标样式或位置)传达给有视觉的用户。标准化元素在浏览器中内置了此语义信息,但对于自定义组件,您需要使用 ARIA 添加信息。

一般来说,任何侦听鼠标单击或悬停事件的组件都应具有某种键盘事件侦听器 ARIA 角色,可能还包括 ARIA 状态和属性。

例如,自定义 <fancy-slider> UI 组件可能采用 slider 的 ARIA 角色,该角色具有一些相关的 ARIA 属性:aria-valuenowaria-valueminaria-valuemax。通过将这些属性绑定到自定义组件上的相关属性,您可以允许辅助技术用户与元素交互、更改其值,甚至使元素的视觉呈现效果也相应更改。

A screenshot of a slider.
范围滑块组件。
<fancy-slider role="slider" aria-valuemin="1" aria-valuemax="5" aria-valuenow="2.5">
</fancy-slider>

用户是否可以在不依赖颜色的情况下理解所有内容?

颜色不应仅用作传达信息的手段,例如指示状态、提示用户做出响应或可视化数据。例如,如果您有一个饼图,请为每个切片提供标签和值,以便视觉障碍用户可以理解信息,即使他们看不到切片的开始和结束位置

A pie chart with labels and values to ensure accessibility.
可访问的饼图。(来自 W3C Web 无障碍功能倡议。)

是否有足够的对比度?

您的组件中显示的任何文本内容都应满足最低 WCAG AA 级对比度阈值。考虑提供满足更高 AAA 阈值的高对比度主题,并确保在用户需要自定义对比度或不同颜色时可以应用用户代理样式表。在设计组件时,您可以使用此颜色对比度检查器作为辅助工具。

移动或闪烁的内容是否可停止且安全?

用户应该能够暂停、停止或隐藏移动、滚动或闪烁时间超过五秒的内容。一般来说,请避免闪烁内容。

如果必须闪烁某些内容,请确保其闪烁频率不超过每秒三次。

无障碍功能工具和测试

有 100 多种工具可用于评估您的网站及其组件的无障碍功能。有些工具是自动化的,而另一些工具则需要手动测试。

以下是一些供您参考的工具

  • Axe 为您的框架或选择的浏览器提供自动化的无障碍功能测试。Axe Puppeteer 可用于编写自动化的无障碍功能测试。
  • Lighthouse 无障碍功能审核提供了有用的见解,可用于发现常见的无障碍功能问题。无障碍功能得分是基于 Axe 用户影响评估的所有无障碍功能审核的加权平均值。有关使用持续集成监控无障碍功能的信息,请参阅 Lighthouse CI

    Screenshot of the Lighthouse accessibility audit.

  • Tenon.io 对于测试常见的无障碍功能问题很有用。Tenon 在构建工具、浏览器(通过扩展程序)甚至文本编辑器中都具有强大的集成支持。

  • 有许多特定于库和框架的工具可以突出显示组件的无障碍功能问题。例如,使用 eslint-plugin-jsx-a11y 来突出显示编辑器中 React 组件的无障碍功能问题。

    Screenshot of a code editor with an accessibility issue flagged by eslint-plugin-jsx-a11y.

    如果您使用 Angular,codelyzer 也提供编辑器内无障碍功能审核

    Screenshot of a code editor with an accessibility issue flagged by codelyzer.

与辅助技术配合使用

  • 您可以使用 Accessibility Inspector (Mac) 或 Windows Automation API Testing ToolsAccProbe (Windows) 检查辅助技术查看 Web 内容的方式。您还可以通过导航到 about://accessibility 来查看 Chrome 创建的完整辅助功能树。
  • 在 Mac 上测试屏幕阅读器支持的最佳方法是使用 VoiceOver 实用工具。使用 ⌘F5 启用或禁用它,使用 Ctrl+Option ←→ 在页面中移动,并使用 Ctrl+Shift+Option + ↑↓ 在辅助功能树中向上和向下移动。有关更详细的说明,请参阅 VoiceOver 命令的完整列表VoiceOver Web 命令列表
  • 在 Windows 上,NVDA 是一个免费的开源屏幕阅读器。但是,对于有视觉的用户来说,它的学习曲线很陡峭。

    Screenshot of ChromeLens.

  • ChromeOS 有一个内置屏幕阅读器

我们在改进 Web 上的无障碍功能方面还有很长的路要走。根据 Web Almanac

  • 每 5 个网站中就有 4 个网站的文本与背景融为一体,导致文本无法阅读。
  • 49.91% 的页面仍未为其某些图像提供 alt 属性。
  • 只有 24% 的使用按钮或链接的页面包含标签。
  • 只有 22.33% 的页面为其所有表单输入提供标签。

我们可以做很多事情来构建对所有人更无障碍的体验。