Skip to content

无障碍概述与原则

Web 无障碍(Web Accessibility,简称 a11y)是指让所有人——包括残障人士、老年人和使用不同设备的用户——都能平等地访问和使用网站内容。HTML 作为 Web 的基石,天然具备丰富的无障碍特性,理解并善用这些特性是每个前端开发者的基本素养。本节将介绍无障碍的核心理念、WCAG 四大原则,以及为什么无障碍对每个网站都至关重要。

前置知识

阅读本节前,建议先了解:Audio API 可视化

什么是 Web 无障碍

Web 无障碍指网站、工具和技术的设计和开发,使得残障人士能够有效地与之交互。这里的"残障"涵盖范围很广:

  • 视觉障碍:全盲、低视力、色盲
  • 听觉障碍:耳聋、听力减退
  • 运动障碍:无法使用鼠标、精细动作困难
  • 认知障碍:学习障碍、记忆力问题、注意力缺陷
  • 临时性障碍:手臂骨折、暂时性视力下降

无障碍 ≠ 仅针对残障人士

良好的无障碍设计同样惠及:使用移动设备的用户、网络慢的用户、老年用户、在强光下使用手机的用户等。据统计,全球约有 15% 的人口拥有某种形式的残障。

WCAG 四大原则

WCAG(Web Content Accessibility Guidelines)是由 W3C 制定的国际标准,目前最新版本为 WCAG 2.2。WCAG 围绕 四大原则(POUR)组织,每个原则下有具体的指导准则。

1. 可感知(Perceivable)

信息和用户界面组件必须以可被用户感知的方式呈现。

准则编号准则名称核心要求
1.1文本替代所有非文本内容必须有等效的文本替代(如 alt 属性)
1.2时基媒体为音频和视频提供字幕、描述文本和替代内容
1.3适应性内容在不同呈现方式下保持可用(如内容结构、顺序)
1.4可辨别内容与背景有足够对比度、文本可缩放、不依赖颜色传达信息
html
<!-- 可感知:图片提供文本替代 -->
<img src="chart.png" alt="2024年销售额柱状图,Q1: 120万,Q2: 150万,Q3: 180万,Q4: 200万" />

<!-- 可感知:不依赖颜色传达信息 -->
<!-- 错误:仅用红色标记错误 -->
<p style="color: red;">此字段必填</p>

<!-- 正确:同时使用图标和文字 -->
<p><span aria-hidden="true">⚠️</span> 错误:此字段为必填项</p>

2. 可操作(Operable)

用户界面组件和导航必须可被操作。

准则编号准则名称核心要求
2.1键盘可访问所有功能可通过键盘操作
2.2充足时间为用户提供足够时间阅读和使用内容
2.3癫痫发作预防不包含每秒闪烁超过 3 次的内容
2.4可导航提供导航、定位和查找内容的手段
2.5输入模态使 Web 内容更易于通过多种输入方式操作
html
<!-- 可操作:自定义按钮支持键盘交互 -->
<div role="button" tabindex="0" onclick="handleClick()" onkeydown="if(event.key==='Enter')handleClick()">
  提交订单
</div>

<!-- 更好的做法:使用原生 button 元素 -->
<button type="button" onclick="handleClick()">提交订单</button>

3. 可理解(Understandable)

信息和用户界面操作必须可被理解。

准则编号准则名称核心要求
3.1可读文本内容可读且可理解
3.2可预测页面行为具有一致性,不会令用户困惑
3.3输入辅助帮助用户避免和纠正错误
html
<!-- 可理解:明确的表单标签和错误提示 -->
<form>
  <label for="email">电子邮箱</label>
  <input type="email" id="email" name="email" required
         aria-describedby="email-error" />
  <span id="email-error" role="alert">请输入有效的邮箱地址</span>
</form>

<!-- 可理解:一致的导航模式 -->
<nav aria-label="主导航">
  <ul>
    <li><a href="/">首页</a></li>
    <li><a href="/products">产品</a></li>
    <li><a href="/about">关于</a></li>
  </ul>
</nav>

4. 健壮性(Robust)

内容必须能被各种用户代理(包括辅助技术)可靠地解析。

准则编号准则名称核心要求
4.1兼容内容与当前和未来的用户代理兼容
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>
  <!-- 使用语义化 HTML 元素 -->
  <header>...</header>
  <main>...</main>
  <footer>...</footer>
</body>
</html>

WCAG 合规级别

WCAG 定义了三个合规级别:

级别说明适用场景
A最低级别,满足基本无障碍要求所有网站都应达到
AA中间级别,解决大多数无障碍问题法律和行业标准通常要求此级别
AAA最高级别,提供最佳无障碍体验特定内容或场景建议达到

合规级别说明

AA 级别是大多数法律法规和行业标准的最低要求,包括欧盟的 EN 301 549、美国的 Section 508 等。大多数公共网站和商业网站应至少达到 AA 级别。

为什么无障碍重要

法律与合规

全球越来越多的国家和地区通过立法要求数字产品具备无障碍功能:

地区/法规简述
美国 ADA禁止歧视残障人士,适用于网站和应用程序
美国 Section 508联邦机构电子和信息技术必须可访问
欧盟 EN 301 549欧盟无障碍指令,适用于公共部门网站和移动应用
欧洲无障碍法案(EAA)2025年起适用于更多产品和服务的无障碍要求
中国《信息技术 无障碍设计规范》GB/T 37668 标准

商业价值

良好的无障碍设计带来多方面的商业利益:

  1. 扩大用户群体:全球超过 10 亿人拥有某种形式的残障
  2. 提升 SEO 排名:语义化 HTML、清晰的 heading 层级、图片 alt 文本等无障碍实践直接提升 SEO
  3. 改善所有用户体验:无障碍设计通常使网站对所有用户都更易用
  4. 降低法律风险:避免因无障碍不达标而面临的法律诉讼

技术收益

无障碍驱动的最佳实践同样提升整体代码质量:

  • 语义化 HTML 使代码更易理解和维护
  • 良好的键盘导航提升所有用户的交互效率
  • 清晰的内容结构改善 SEO 和代码可读性
  • 适当的标注和标签使组件更易于复用和测试

无障碍评估方法

自动化检测

自动化工具可以快速发现约 30% 的无障碍问题:

javascript
// 使用 axe-core 进行自动化检测
// npm install axe-core
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>无障碍检测示例</title>
</head>
<body>
  <script src="https://cdn.jsdelivr.net/npm/axe-core@latest"></script>
  <script>
    // 对整个页面运行无障碍检测
    axe.run(document, {
      runOnly: ['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'],
      // 排除特定规则
      rules: {
        'color-contrast': { enabled: true }
      }
    }).then(results => {
      if (results.violations.length > 0) {
        console.log('发现 ' + results.violations.length + ' 个违规:');
        results.violations.forEach(violation => {
          console.log(`[${violation.impact}] ${violation.description}`);
          violation.nodes.forEach(node => {
            console.log('  目标:', node.target.join(', '));
          });
        });
      } else {
        console.log('未发现无障碍违规!');
      }
    });
  </script>
</body>
</html>

手动检测清单

以下是需要人工检查的关键项目:

HTML 原生无障碍特性

HTML 提供了许多内置的无障碍支持:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>HTML 原生无障碍特性</title>
</head>
<body>
  <!-- 1. 语义化标签提供结构信息 -->
  <header>
    <nav aria-label="主导航">
      <a href="#main-content">跳到主要内容</a>
    </nav>
  </header>

  <main id="main-content">
    <!-- 2. heading 层级提供文档大纲 -->
    <h1>产品列表</h1>

    <section>
      <h2>电子设备</h2>

      <!-- 3. button 元素自动支持键盘交互 -->
      <button type="button">添加到购物车</button>

      <!-- 4. label 关联表单控件 -->
      <label for="quantity">数量</label>
      <input type="number" id="quantity" min="1" max="99" />

      <!-- 5. table 的 caption 和 scope -->
      <table>
        <caption>产品规格表</caption>
        <thead>
          <tr>
            <th scope="col">属性</th>
            <th scope="col">规格</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <th scope="row">重量</th>
            <td>200g</td>
          </tr>
        </tbody>
      </table>
    </section>

    <!-- 6. details/summary 实现可展开内容 -->
    <details>
      <summary>查看更多信息</summary>
      <p>这是额外的产品描述信息...</p>
    </details>
  </main>

  <footer>
    <p>版权所有 2024</p>
  </footer>
</body>
</html>

无障碍开发的核心理念

原生优先

始终优先使用原生 HTML 元素,而不是用 <div> 和 JavaScript 重新实现:

html
<!-- 不推荐:自定义按钮 -->
<div class="btn" onclick="submit()">提交</div>

<!-- 推荐:原生按钮 -->
<button type="submit">提交</button>

<!-- 不推荐:自定义下拉菜单 -->
<div class="custom-select">
  <div class="selected" onclick="toggleMenu()">请选择</div>
  <div class="options">
    <div onclick="select('A')">选项 A</div>
    <div onclick="select('B')">选项 B</div>
  </div>
</div>

<!-- 推荐:原生 select -->
<select name="choice">
  <option value="">请选择</option>
  <option value="A">选项 A</option>
  <option value="B">选项 B</option>
</select>

渐进增强

从基本的可用性出发,逐步添加增强功能:

html
<!-- 基础:即使 JavaScript 禁用也能工作 -->
<form action="/search" method="get">
  <label for="q">搜索</label>
  <input type="search" id="q" name="q" />
  <button type="submit">搜索</button>
</form>

<!-- 增强:添加自动完成建议 -->
<script>
  // 增强:在基础功能上添加搜索建议
  const input = document.getElementById('q');
  input.addEventListener('input', debounce(showSuggestions, 300));
</script>

实战示例:一个无障碍友好的卡片组件

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>
  <style>
    /* 卡片基础样式 */
    .card {
      border: 1px solid #e0e0e0;
      border-radius: 8px;
      padding: 1rem;
      max-width: 300px;
    }

    /* 焦点样式:清晰的视觉指示 */
    .card:focus-within {
      outline: 3px solid #0066cc;
      outline-offset: 2px;
    }

    .card img {
      width: 100%;
      height: auto;
      display: block;
    }

    .card h2 {
      font-size: 1.25rem;
      margin: 0.5rem 0;
    }

    .card p {
      color: #666;
      font-size: 0.9rem;
    }

    .card-link {
      display: inline-block;
      margin-top: 0.5rem;
      color: #0066cc;
      text-decoration: underline;
    }
  </style>
</head>
<body>
  <!-- 使用 article 表示独立内容块 -->
  <article class="card">
    <!-- 有意义的 alt 文本 -->
    <img src="product.jpg" alt="无线蓝牙耳机,黑色,入耳式设计" />

    <!-- heading 提供标题 -->
    <h2>无线蓝牙耳机</h2>

    <!-- 正文描述 -->
    <p>高品质无线蓝牙耳机,支持主动降噪,续航 30 小时。</p>

    <!-- 价格信息 -->
    <p><strong>¥299.00</strong></p>

    <!-- 链接有描述性文本 -->
    <a href="/products/headphones" class="card-link" aria-label="查看无线蓝牙耳机详情">
      查看详情
    </a>
  </article>
</body>
</html>

注意事项

  1. 无障碍不是"锦上添花":它应从一开始就融入设计和开发流程,而非事后补救
  2. 自动化工具不充分:工具只能检测约 30% 的问题,必须结合手动测试
  3. 不要仅依赖 ARIA:原生 HTML 语义通常优于 ARIA 覆盖
  4. 考虑临时性障碍:比如用户在明亮阳光下使用手机、手臂受伤等场景
  5. 测试真实用户:尽可能让使用辅助技术的真实用户参与测试

最佳实践

  • 在项目开始时就建立无障碍标准,并在整个开发周期中持续执行
  • 使用语义化 HTML 元素(<header><main><nav><button> 等)
  • 为所有非文本内容提供文本替代(altaria-label
  • 确保键盘可以操作所有交互功能
  • 维护正确的 heading 层级(h1 → h2 → h3,不跳级)
  • 在设计和开发阶段都进行无障碍测试
  • 将无障碍检查集成到 CI/CD 流程中

下一节

继续学习:ARIA 角色(role)

参考链接