面向 Web 开发者的无障碍功能

提高无障碍功能可让所有人更轻松地使用您的网站。

Addy Osmani
Addy Osmani

请务必打造包容且人人都能访问的网站。 您至少可以针对以下六个关键的残障人士体验方面进行优化:视觉听觉行动认知语音神经。许多工具和资源都可以帮助您实现无障碍功能,即使您完全不了解无障碍网站。

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

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

以下是用户可能存在的一些残障:

Vision 听力 行动不便
  • 低视力
  • 盲人
  • 色盲
  • 白内障
  • 太阳眩光
  • 听障
  • 失聪
  • 噪音
  • 耳部感染
  • 脊髓损伤
  • 灵活性有限
  • 双手被占用
认知 语音 Neural
  • 学习障碍
  • 睡意或分心
  • 偏头痛
  • 孤独症
  • 癫痫
  • 环境噪声
  • 咽喉痛
  • 口齿不清
  • 无法说话
  • 忧郁症
  • PTSD
  • 躁郁症
  • 焦虑

视觉问题包括无法分辨颜色到完全失明。

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

Chrome DevTools 中“Inspect Element”(检查元素)工具提示的屏幕截图。

我个人是弱视人士,经常需要放大网站、其 DevTools 和终端。虽然支持缩放功能几乎从来不在开发者的待办事项列表的首位,但对像我这样的用户来说,它却能起到至关重要的作用。

听力问题是指用户可能无法听到网页发出的声音。

ChromeVox 屏幕阅读器朗读网页的屏幕截图。

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

  • 让界面组件的内容可通过键盘执行功能,以便用户执行原本需要使用鼠标的操作。
  • 确保网页已针对辅助技术(包括屏幕阅读器、语音控制软件和实体开关控件)正确标记,这些辅助技术通常使用相同的 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;
      }
    }
    
  • 避免基于时间的互动。

这似乎需要涵盖很多方面,但我们将详细介绍评估界面组件无障碍功能并加以改进的过程。

为了提供额外的视觉支持,GOV.UK 无障碍团队制作了一系列无障碍做法和禁忌数字海报,您可以使用这些海报与团队分享最佳实践。

显示无障碍功能注意事项的数字海报。
六张海报,列出了无障碍功能最佳实践。阅读完整文本

衡量界面组件无障碍功能

在审核网页的界面组件是否符合无障碍要求时,请自问:

  • 您能否仅使用键盘使用界面组件?

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

  • 您的界面组件能否与屏幕阅读器搭配使用?

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

  • 您的界面组件在静音模式下能否正常运行?

    关闭音箱,然后演示您的用例。

  • 您的界面组件在没有颜色的情况下能否正常运行?

    确保您的界面组件可供色盲人士使用。一款名为 Colorblindly 的 Chrome 扩展程序非常适合模拟色盲。(试用所有四种色盲模拟形式。) 您可能还对 Daltonize 扩展程序感兴趣,它也非常实用。

  • 您的界面组件是否可以在启用高对比度模式的情况下正常运行?

    所有新型操作系统都支持高对比度模式。高对比度是一款 Chrome 扩展程序,可在此方面提供帮助。

标准控件(例如 <button><select>)已内置到浏览器中。您可以使用 Tab 键对其聚焦;它们会响应键盘事件(例如 EnterSpace 和箭头键);并且它们具有无障碍工具使用的语义角色、状态和属性。它们的默认样式也应符合所列的无障碍功能要求。

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

大多数浏览器开发者工具都支持检查网页的无障碍功能树。在 Chrome 开发者工具中,此功能位于 Elements 面板的 Accessibility 标签页中。

Chrome DevTools 中无障碍功能树视图的屏幕截图。

Firefox 还提供无障碍面板。

Firefox DevTools 中无障碍功能树状视图的屏幕截图。

Safari 会在元素面板的节点标签页中显示无障碍功能信息。

以下是您在尝试提高界面组件的易用性时可以问自己的一系列问题。

改进键盘焦点

理想情况下,应确保界面组件中的所有功能都可以通过键盘访问。在设计用户体验时,请考虑如何仅使用键盘使用元素,并确定一组一致的键盘互动。

首先,确保为每个组件设置了合理的焦点目标。例如,菜单等复杂组件可以是网页中的焦点目标,但之后应自行管理焦点,以便活跃的菜单项始终获得焦点。

一张屏幕截图,显示了需要管理焦点的菜单和子菜单。
管理复杂元素中的焦点。

使用 tabindex

您可以使用 tabindex 属性为元素和界面组件添加键盘焦点。仅使用键盘的用户和辅助技术用户需要能够将键盘焦点放在元素上,以便与其互动。

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

tabindex 值有三种类型:

  • tabindex="0" 是最常见的,它会将元素放置在自然 Tab 键顺序(由 DOM 顺序定义)中。
  • 如果 tabindex 值等于 -1,则会导致元素可通过程序化方式获得焦点,但不会出现在标签页顺序中。
  • tabindex 值大于 0 会将元素放入手动 Tab 键顺序中。页面中具有正 tabindex 值的所有元素都会按数字顺序访问,先于自然 Tab 键顺序中的元素。

如需了解 tabindex 的一些用例,请参阅使用 tabindex一文。

确保焦点始终可见,无论是使用默认的焦点圈样式,还是应用清晰可辨的自定义焦点样式。请注意,不要困住键盘用户 - 他们应该能够仅使用键盘将焦点从某个元素移开。

使用自动对焦功能

借助 HTML autofocus 属性,作者可以指定特定元素应在网页加载时自动获得焦点。所有 Web 表单控件(包括按钮)均已支持 autofocus。如需在您自己的自定义界面组件中自动对元素聚焦,请调用 focus() 方法,该方法适用于所有可聚焦的 HTML 元素(例如 document.querySelector('myButton').focus())。

添加键盘互动

界面组件可获得焦点后,请通过处理适当的键盘事件,在组件获得焦点时提供良好的键盘互动体验。例如,允许用户使用箭头键选择菜单选项,并使用 SpaceEnter 激活按钮。ARIA 设计模式指南提供了一些相关指导。

最后,确保您的键盘快捷键可供发现。常见做法是显示键盘快捷键图例(屏幕上的文本),以告知用户存在快捷键。例如,“按 ? 键盘快捷键。”或者,您也可以使用提示(例如提示工具)告知用户快捷方式。

管理专注度的重要性怎么强调都不为过。一个重要的示例是抽屉式导航栏。如果您向页面添加界面组件,则需要将焦点引导至其中的元素;否则,用户可能必须按 Tab 键浏览整个页面才能找到该元素。这可能会给用户带来不良体验,因此请务必测试页面中所有可通过键盘导航的组件的焦点。

WalkMe 状态切换开关测试。
// 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> 界面组件仅显示齿轮图标来指明它是一个设置菜单,则需要提供可访问的文本替代项(例如“设置”),以传达相同的信息。根据上下文,您可以在 Shadow DOM 中使用 alt 属性、aria-label 属性、aria-labelledby 属性或纯文本提供文本替代项。您可以在 WebAIM 快速参考中找到常规技术提示。

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

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

辅助技术可传达视觉用户通过视觉提示(例如格式、光标样式或位置)获得的语义信息。标准化元素由浏览器内置此语义信息,但对于自定义组件,您需要使用 ARIA 添加此信息。

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

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

滑块的屏幕截图。
范围滑块组件。
<fancy-slider role="slider" aria-valuemin="1" aria-valuemax="5" aria-valuenow="2.5">
</fancy-slider>

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

颜色不应是传达信息(例如指示状态、提示用户做出回应或直观呈现数据)的唯一方式。例如,如果您使用的是饼图,请为每个切片提供标签和值,以便视障用户能够理解相关信息,即使他们看不到切片的起点和终点也是如此:

包含标签和值的饼图,以确保无障碍。
一张可访问的饼图。(摘自 W3C 网站无障碍计划。)

对比度是否足够?

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

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

如果内容会移动、滚动或闪烁超过 5 秒,用户应能够暂停、停止或隐藏该内容。一般而言,请避免闪烁内容。

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

无障碍功能工具和测试

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

以下是一些建议供您参考:

  • Axe 可为您选择的框架或浏览器提供自动化无障碍测试。Axe Puppeteer 可用于编写自动化无障碍功能测试。
  • Lighthouse 无障碍功能审核可提供有用的分析洞见,帮助您发现常见的无障碍功能问题。无障碍功能得分是根据 Axe 用户影响评估对所有无障碍功能审核结果的加权平均值。如需了解如何通过持续集成监控无障碍功能,请参阅 Lighthouse CI

    Lighthouse 无障碍功能审核的屏幕截图。

  • Tenon.io 非常适合测试常见的无障碍功能问题。Tenon 在构建工具、浏览器(通过扩展程序)甚至文本编辑器方面都提供了强大的集成支持。

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

    代码编辑器的屏幕截图,其中显示了 eslint-plugin-jsx-a11y 标记的无障碍问题。

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

    代码编辑器的屏幕截图,其中显示了 Codelyzer 标记的无障碍问题。

使用辅助技术

  • 您可以使用无障碍功能检查器 (Mac) 或 Windows 自动化 API 测试工具AccProbe (Windows) 检查辅助技术查看 Web 内容的方式。您还可以前往 about://accessibility,查看 Chrome 创建的完整无障碍功能树。
  • 在 Mac 上测试屏幕阅读器支持的最佳方法是使用 VoiceOver 实用程序。使用 ⌘F5 启用或停用此功能,使用 Ctrl+Option ←→ 浏览页面,使用 Ctrl+Shift+Option + ↑↓ 在无障碍功能树中上下移动。如需更详细的说明,请参阅 VoiceOver 命令的完整列表VoiceOver Web 命令列表
  • 在 Windows 上,NVDA 是一款免费的开源屏幕阅读器。不过,对于视力正常的用户来说,学习曲线较陡。

    ChromeLens 的屏幕截图。

  • ChromeOS 内置了屏幕阅读器

我们仍需努力,才能进一步提升网络无障碍性。 根据 Web Almanac(网络年鉴):

  • 每 5 个网站中就有 4 个网站的文本与背景融为一体,无法辨认。
  • 49.91% 的网页仍未为部分图片提供 alt 属性。
  • 只有 24% 使用按钮或链接的网页包含标签。
  • 只有 22.33% 的网页为其所有表单输入项提供了标签。

我们可以做很多工作来打造更易于所有人访问的体验。