Developer Tools

网页无障碍访问(a11y):开发者实用指南

学习必要的无障碍原则、ARIA 属性、键盘导航模式以及测试工具,让你的网页应用对所有人都可用。

8分钟阅读

使用辅助技术操作笔记本电脑的人

全球超过 13 亿人——占世界人口的 16%——患有某种形式的残障。网页无障碍访问确保你的网站能够服务于依赖屏幕阅读器、键盘导航、开关控制或其他辅助技术的用户。除了包容性之外,无障碍网站在搜索中排名更高、在移动端表现更好,而且通常也是法律的要求。

四大 POUR 原则

网页内容无障碍指南(WCAG)建立在四个核心原则之上。内容必须做到:

  1. 可感知(Perceivable) — 信息必须以用户能够感知的方式呈现(不仅限于视觉)。
  2. 可操作(Operable) — 所有功能必须可通过键盘使用。
  3. 可理解(Understandable) — 内容和界面必须易于理解。
  4. 健壮性(Robust) — 内容必须能被辅助技术解析。

WCAG 2.2 定义了三个合规级别:

  • A — 最低标准(必须达到)
  • AA — 大多数组织的标准目标
  • AAA — 最高标准(部分内容的理想目标)

大多数法律要求(ADA、EN 301 549、EAA)都要求达到 AA 合规

优先使用语义化 HTML

对无障碍访问影响最大的事情就是为任务选用正确的 HTML 元素。浏览器和屏幕阅读器本身就知道如何处理语义化元素:

<!-- ❌ Div 堆砌 — 没有语义 -->
<div class="header">
  <div class="nav">
    <div class="nav-item" onclick="navigate()">Home</div>
  </div>
</div>

<!-- ✅ 语义化 HTML — 屏幕阅读器可以理解 -->
<header>
  <nav>
    <a href="/">Home</a>
  </nav>
</header>

关键语义化元素及其作用:

元素 作用
<header><footer> 地标区域
<nav> 导航地标
<main> 主要内容(每页一个)
<aside> 补充内容
<h1><h6> 标题层级
<button> 交互控件
<a href> 导航链接
<label> 表单字段标签
<table> 表格数据

图片与替代文本

每张有意义的图片都需要一个描述其内容的 alt 属性。装饰性图片使用空的 alt="",让屏幕阅读器跳过它们:

<!-- 有意义的图片 -->
<img src="chart.png" alt="Bar chart showing 40% increase in revenue Q1 2026">

<!-- 装饰性图片 -->
<img src="divider.svg" alt="">

<!-- 图标按钮 — 描述操作,而非图标本身 -->
<button>
  <img src="trash.svg" alt="Delete item">
</button>

<!-- 避免:冗余的"图片是"表述 -->
<!-- ❌ --> <img src="cat.jpg" alt="Image of a cat">
<!-- ✅ --> <img src="cat.jpg" alt="Orange tabby cat sitting on a windowsill">

色彩对比度

有低视力或色觉障碍的用户依赖文本与背景之间足够的对比度。

WCAG AA 要求:

  • 普通文本(< 18pt):最低 4.5:1 对比度
  • 大文本(≥ 18pt 或 14pt 粗体):最低 3:1 对比度
  • UI 组件和图形对象:最低 3:1

不要仅靠颜色来传递信息:

<!-- ❌ 仅用颜色表示状态 -->
<span class="text-red-500">Error</span>

<!-- ✅ 颜色 + 图标 + 文字 -->
<span class="text-red-500 flex items-center gap-1">
  <svg aria-hidden="true"><!-- error icon --></svg>
  Error: Invalid email address
</span>

表单:标签、错误提示与说明

每个表单控件都需要一个可见的关联标签:

<!-- ✅ 显式标签关联 -->
<label for="email">Email address</label>
<input id="email" type="email" aria-describedby="email-hint email-error">
<p id="email-hint" class="text-sm text-gray-500">We'll never share your email.</p>
<p id="email-error" role="alert" class="text-sm text-red-600" hidden>
  Please enter a valid email address.
</p>

表单无障碍的关键模式:

  • 使用 for/id 将标签与输入框关联
  • 使用 aria-describedby 提供提示文本和错误信息
  • 使用 role="alert"aria-live="polite" 处理动态错误提示
  • 使用 aria-required="true" 或原生 required 属性
  • 使用 <fieldset><legend> 将相关输入项分组

键盘导航

所有交互元素必须可通过键盘访问和操作:

  • Tab — 向前移动焦点至可聚焦元素
  • Shift+Tab — 向后移动
  • Enter/Space — 激活按钮、复选框
  • 方向键 — 在组件内导航(菜单、标签页、滑块)
  • Escape — 关闭模态框、收起下拉菜单

焦点指示器必须可见。在没有替代方案的情况下,绝对不要这样做:

/* ❌ 完全隐藏焦点指示器 */
*:focus { outline: none; }

/* ✅ 自定义焦点样式,仍然可见 */
*:focus-visible {
  outline: 2px solid #3b82f6;
  outline-offset: 2px;
}

ARIA:何时使用以及如何使用

ARIA(Accessible Rich Internet Applications)属性在 HTML 本身不足以表达语义时,为元素添加语义信息。ARIA 第一条规则:如果原生 HTML 可以胜任,就不要使用 ARIA

<!-- 为没有可见标签的元素添加标签 -->
<button aria-label="Close dialog">✕</button>

<!-- 描述展开状态 -->
<button aria-expanded="false" aria-controls="menu">Menu</button>
<ul id="menu" hidden>...</ul>

<!-- 动态内容的实时区域 -->
<div aria-live="polite" aria-atomic="true">
  <!-- 屏幕阅读器会朗读此区域的变化 -->
  3 results found
</div>

<!-- 当语义化元素不可用时使用地标角色 -->
<div role="search">
  <input type="search" placeholder="Search...">
</div>

单页应用与模态框的焦点管理

在单页应用中,页面导航不会触发浏览器的焦点重置。当"页面"加载时,应将焦点移动到有意义的位置:

// 导航后,将焦点移至主标题
document.querySelector("h1")?.focus();

对于模态框:

  1. 模态框打开时,将焦点移至其内部第一个可聚焦元素
  2. 模态框打开期间,将焦点锁定在其内部(防止 Tab 键访问背后的内容)
  3. 模态框关闭时,将焦点返回到触发它的元素

无障碍测试

自动化工具(可发现约 30-40% 的问题)

  • axe DevTools 浏览器扩展
  • Lighthouse Chrome DevTools 中的无障碍审计
  • WAVE 浏览器扩展

手动测试(完整覆盖所必需)

  1. 纯键盘导航 — 拔掉鼠标,仅用键盘浏览整个网站
  2. 屏幕阅读器测试 — NVDA + Firefox(Windows)、VoiceOver + Safari(Mac/iOS)
  3. 放大到 200% — 确保内容不会丢失或重叠
  4. 色盲模拟 — 浏览器 DevTools → Rendering → Emulate vision deficiencies

可读性

简明语言有助于认知障碍用户的无障碍访问。使用我们的可读性评分工具检查内容的阅读难度——面向大众的内容建议控制在 8-10 年级阅读水平。

今天就能实现的快速改进

  1. 为所有图片添加 alt 文本
  2. 确保所有表单输入项都有关联的 <label> 元素
  3. 检查正文文本的色彩对比度是否达到 4.5:1
  4. 添加 :focus-visible 样式,不要在没有替代方案的情况下移除轮廓线
  5. <button> 表示操作,用 <a href> 表示导航(不要反过来用)
  6. <html> 元素上添加 lang="en"(或适当的语言代码)
  7. 每页使用一个 <h1>,并保持合理的标题层级结构

无障碍访问不是附加功能——它是产品质量的体现。从一开始就构建无障碍产品,远比事后改造成本更低,也能让你的产品对所有人都更友好。