Web无障碍开发指南 - WCAG标准实践

前端最佳实践 作者: 编辑团队 发布于: 2026-06-20 阅读约 14 分钟

为什么Web无障碍很重要?

Web无障碍(Accessibility,简称A11y)确保所有用户,包括残障人士,都能平等地访问和使用Web内容。全球约有15亿人(约占世界人口的16%)存在某种形式的残障,无障碍设计不是可选项,而是Web开发的基本责任。

此外,许多国家和地区已将Web无障碍纳入法律法规。例如,欧盟的《欧洲无障碍法案》(EAA)要求到2025年6月,所有数字产品和服务必须满足无障碍标准。

Web无障碍的核心理念是"人人可用"(Universal Access)——Tim Berners-Lee,万维网之父

WCAG 2.1 四大原则(POUR)

WCAG(Web Content Accessibility Guidelines)是Web无障碍的国际标准,其核心围绕四大原则展开:

原则 英文 含义 关键要求
可感知 Perceivable 信息和界面组件必须以用户可感知的方式呈现 文本替代、字幕、可调整的内容呈现
可操作 Operable 界面组件和导航必须可操作 键盘可访问、足够的时间、无癫痫诱因
可理解 Understandable 信息和用户界面操作必须可理解 可读性、可预测性、输入辅助
健壮性 Robust 内容必须足够健壮,能被各种用户代理解析 兼容辅助技术、有效的HTML

语义化HTML基础

使用正确的HTML元素是实现无障碍的第一步。语义化标签不仅让代码更易读,更重要的是为辅助技术提供必要的结构信息。

正确的文档结构

<!-- 正确的语义化结构 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>页面标题 - 网站名称</title>
</head>
<body>
  <header>
    <nav aria-label="主导航">
      <ul>
        <li><a href="/">首页</a></li>
        <li><a href="/about">关于</a></li>
      </ul>
    </nav>
  </header>

  <main id="main-content">
    <article>
      <h1>页面主标题</h1>
      <section aria-labelledby="section-1">
        <h2 id="section-1">第一节</h2>
        <p>内容...</p>
      </section>
    </article>
  </main>

  <footer>
    <p>&copy; 2026 网站名称</p>
  </footer>
</body>
</html>

避免的反模式

<!-- 不推荐:使用 div 模拟按钮 -->
<div class="btn" onclick="handleClick()">点击我</div>

<!-- 不推荐:空的链接 -->
<a href="/page"></a>

<!-- 推荐:使用语义化元素 -->
<button type="button" onclick="handleClick()">点击我</button>

<!-- 推荐:链接提供有意义的文本 -->
<a href="/page">查看详细内容</a>

ARIA 属性详解

ARIA(Accessible Rich Internet Applications)属性为动态内容和复杂UI组件提供额外的无障碍信息。但切记:ARIA的第一条规则是——如果能用原生HTML实现,就不要用ARIA。

常用ARIA角色

<!-- 标记为警告信息 -->
<div role="alert" aria-live="assertive">
  提交成功!
</div>

<!-- 标记为加载状态 -->
<div role="status" aria-live="polite">
  正在加载中...
</div>

<!-- 标签页组件 -->
<div role="tablist" aria-label="内容标签">
  <button role="tab" aria-selected="true" aria-controls="panel-1">
    标签一
  </button>
  <button role="tab" aria-selected="false" aria-controls="panel-2">
    标签二
  </button>
</div>
<div role="tabpanel" id="panel-1">内容一</div>
<div role="tabpanel" id="panel-2" hidden>内容二</div>

常用ARIA属性速查

属性 用途 示例
aria-label 为元素提供可读标签 <button aria-label="关闭对话框">×</button>
aria-labelledby 引用其他元素作为标签 <div aria-labelledby="title1">
aria-describedby 引用元素提供补充描述 <input aria-describedby="hint1">
aria-hidden 对辅助技术隐藏元素 <span aria-hidden="true"> decorative icon </span>
aria-expanded 指示展开/折叠状态 <button aria-expanded="false">菜单</button>
aria-required 标记必填字段 <input aria-required="true">

颜色对比度

颜色对比度是WCAG中的重要要求,确保视力低下或色盲用户能够清晰阅读文本内容。

对比度要求

级别 正文文本 大号文本(18px+粗体或24px+) UI组件
AA(最低要求) 4.5:1 3:1 3:1
AAA(推荐) 7:1 4.5:1
/* 使用 CSS 变量确保足够的对比度 */
:root {
  --text-primary: #1a1a2e;     /* 对比度约 16:1 on white */
  --text-secondary: #4a4a6a;   /* 对比度约 7:1 on white */
  --text-muted: #6b7280;       /* 对比度约 4.6:1 on white (AA) */
  --accent: #2563eb;           /* 对比度约 4.5:1 on white */
}

/* 高对比度模式支持 */
@media (prefers-contrast: high) {
  :root {
    --text-primary: #000000;
    --text-secondary: #1a1a1a;
    --text-muted: #333333;
  }
}

/* 暗色模式支持 */
@media (prefers-color-scheme: dark) {
  :root {
    --text-primary: #f0f0f0;
    --text-secondary: #d0d0d0;
    --text-muted: #a0a0a0;
  }
}

键盘导航

许多用户依赖键盘而非鼠标进行网页导航。确保所有交互元素都能通过键盘访问是无障碍的基本要求。

键盘交互规范

焦点管理代码示例

/* 显示焦点指示器 */
:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* 隐藏默认焦点(仅在键盘导航时显示) */
:focus:not(:focus-visible) {
  outline: none;
}

/* 模态框的焦点陷阱 */
function trapFocus(modal) {
  const focusable = modal.querySelectorAll(
    'a[href], button:not([disabled]), input:not([disabled]), ' +
    'select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
  );
  const firstEl = focusable[0];
  const lastEl = focusable[focusable.length - 1];

  modal.addEventListener('keydown', (e) => {
    if (e.key === 'Tab') {
      if (e.shiftKey && document.activeElement === firstEl) {
        e.preventDefault();
        lastEl.focus();
      } else if (!e.shiftKey && document.activeElement === lastEl) {
        e.preventDefault();
        firstEl.focus();
      }
    }
    if (e.key === 'Escape') {
      closeModal(modal);
    }
  });

  firstEl.focus();
}

表单无障碍

表单是Web无障碍中最关键的部分之一。正确的标签关联和错误提示对屏幕阅读器用户至关重要。

<!-- 正确的表单无障碍实践 -->
<form>
  <div class="form-group">
    <label for="username">
      用户名 <span aria-hidden="true">*</span>
      <span class="sr-only">(必填)</span>
    </label>
    <input
      type="text"
      id="username"
      name="username"
      aria-required="true"
      aria-invalid="false"
      aria-describedby="username-hint"
    />
    <span id="username-hint" class="hint">
      请输入4-20个字符的用户名
    </span>
  </div>

  <div class="form-group">
    <label for="email">邮箱地址</label>
    <input
      type="email"
      id="email"
      name="email"
      aria-required="true"
      aria-invalid="true"
      aria-describedby="email-error"
    />
    <span id="email-error" class="error" role="alert">
      请输入有效的邮箱地址
    </span>
  </div>

  <button type="submit">提交</button>
</form>

<!-- 无障碍的跳转链接(仅在聚焦时显示) -->
<style>
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  padding: 8px 16px;
  background: var(--accent);
  color: #fff;
  z-index: 100;
  transition: top 0.3s;
}

.skip-link:focus {
  top: 0;
}
</style>

<a href="#main-content" class="skip-link">跳转到主要内容</a>

图像无障碍

为图像提供恰当的替代文本是图片无障碍的核心要求。

<!-- 信息性图片 -->
<img src="chart.png" alt="2025年销售趋势图,Q3达到峰值120万元">

<!-- 装饰性图片 -->
<img src="decorative-border.png" alt="" role="presentation">

<!-- 图标按钮 -->
<button aria-label="搜索">
  <svg aria-hidden="true">
    <use href="#icon-search"></use>
  </svg>
</button>

<!-- 复杂图表 -->
<figure>
  <img src="complex-chart.png" alt="年度用户增长数据图表">
  <figcaption>
    图1:2024-2025年月度活跃用户增长趋势。
    完整数据见<a href="/data/active-users.csv">CSV文件</a>。
  </figcaption>
</figure>

无障碍测试工具

自动化工具可以检测约30-40%的无障碍问题,但人工测试仍然不可替代。

工具 类型 特点
axe DevTools 浏览器扩展 / API 业界标准,集成于Chrome/Firefox,检测准确率高
Lighthouse Chrome内置 综合审计,包含无障碍评分
NVDA 屏幕阅读器 Windows免费开源,真实的屏幕阅读器体验
VoiceOver 屏幕阅读器 macOS/iOS内置,Safari配合效果最佳
WAVE 在线工具 可视化标注问题,适合初学者
pa11y 命令行/CI 自动化测试,集成到持续集成流程

无障碍检查清单

  1. 所有图片都有适当的 alt 文本
  2. 页面有正确的标题层级(h1 → h2 → h3)
  3. 所有表单元素都有关联的 label
  4. 颜色对比度满足 WCAG AA 标准
  5. 所有功能都可以通过键盘操作
  6. 焦点顺序符合逻辑
  7. 焦点指示器清晰可见
  8. 页面有跳过导航的链接
  9. 使用 ARIA 属性增强复杂组件的无障碍性
  10. 动态内容更新通过 aria-live 通知屏幕阅读器
  11. HTML 通过 W3C 验证
  12. 使用 axe 或 Lighthouse 进行自动化测试