Skip to content

屏幕阅读器兼容

屏幕阅读器是视障用户访问网页的主要工具。了解不同屏幕阅读器的工作原理、对各 HTML 特性的支持差异,以及正确的测试方法,是确保无障碍设计有效落地的关键。本节将介绍主流屏幕阅读器(NVDA、JAWS、VoiceOver)的特点、语义化 HTML 对屏幕阅读器的影响,以及实用的测试方法。

前置知识

阅读本节前,建议先了解:跳过导航链接

主流屏幕阅读器

常见屏幕阅读器一览

屏幕阅读器平台价格市场占有率
NVDAWindows免费开源全球最大
JAWSWindows付费(约 $1000/年)美国市场最大
VoiceOvermacOS / iOS免费(系统内置)Mac 用户标配
TalkBackAndroid免费(系统内置)Android 用户标配
NarratorWindows免费(系统内置)辅助/临时使用

屏幕阅读器的工作原理

解析流程

屏幕阅读器通过以下步骤解析页面:

  1. DOM 解析:获取页面 DOM 树
  2. Accessibility Tree:浏览器将 DOM 转换为无障碍树
  3. 语义提取:从无障碍树中提取语义信息
  4. 播报输出:将语义信息转化为语音或盲文输出
HTML → DOM Tree → Accessibility Tree → 语音/盲文输出

模式概述

屏幕阅读器主要有两种浏览模式:

模式说明操作方式
浏览模式(虚拟光标)自由浏览页面内容方向键、快捷键
表单模式(焦点模式)与表单和交互元素交互Tab、Enter、Space

用户可以在两种模式间切换(通常通过 Tab 键进入表单模式,Escape 键返回浏览模式)。

语义化 HTML 对屏幕阅读器的影响

原生元素 vs 自定义元素

html
<!-- 屏幕阅读器播报:"链接,首页" -->
<a href="/">首页</a>

<!-- 屏幕阅读器播报:"链接,首页"(语义相同) -->
<a href="/" role="link">首页</a>

<!-- 屏幕阅读器播报可能不完整 -->
<div onclick="location.href='/'">首页</div>

heading 层级的影响

html
<!-- 屏幕阅读器使用 heading 快速浏览 -->
<!-- 用户可以按 H 键跳到下一个标题 -->
<!-- Shift+H 跳到上一个标题 -->

<h1>网站标题</h1>
<h2>文章标题</h2>
  <h3>小节标题</h3>
  <h3>另一个小节</h3>
<h2>另一篇文章</h2>

<!-- 屏幕阅读器提供标题导航列表 -->
<!-- 用户可以按 Insert+F6(NVDA)列出所有标题 -->

表单元素

html
<!-- 播报:"用户名,编辑框" -->
<label for="name">用户名</label>
<input type="text" id="name" />

<!-- 播报:"编辑框,用户名"(顺序不同,但信息完整) -->
<input type="text" id="name" aria-label="用户名" />

<!-- 播报不完整:缺少标签 -->
<input type="text" placeholder="用户名" />
<!-- 屏幕阅读器可能只播报:"编辑框" -->

图片替代文本

html
<!-- 播报:"图片,一个微笑的人" -->
<img src="person.jpg" alt="一个微笑的人" />

<!-- 播报:"图片" 或不播报(装饰性图片) -->
<img src="decoration.png" alt="" role="presentation" />

<!-- 播报:"图片,person-dot-jpg"(不推荐) -->
<img src="person.jpg" />

各屏幕阅读器特性

NVDA(NonVisual Desktop Access)

NVDA 是一款免费的 Windows 屏幕阅读器,使用 Python 开发,由 NV Access 维护。

特性说明
快捷键Insert+H:帮助;Insert+F7:元素列表;Insert+T:标题导航
浏览模式支持虚拟光标浏览
浏览器支持主要使用 Firefox(兼容性最佳),也支持 Chrome/Edge
开发者工具NVDA 开发者工具集(用于诊断)
测试方法可免费下载安装进行测试

JAWS(Job Access With Speech)

JAWS 是商业屏幕阅读器,功能强大但价格昂贵。

特性说明
快捷键Insert+F5:表单列表;Insert+F6:标题列表;Insert+F7:链接列表
浏览器支持主要使用 Chrome/Edge(FS 2024 后支持更好)
脚本支持支持自定义脚本扩展功能
测试方法有 40 分钟试用模式;可使用 WebAIM 屏幕阅读器模拟器

VoiceOver(macOS / iOS)

VoiceOver 是苹果系统内置的屏幕阅读器。

特性说明
启动方式macOS:Command+F5;iOS:三击 Home/电源键
快捷键VO+U: rotor;VO+H:标题导航;VO+Command+H:标题列表
浏览器支持Safari(最佳)、Chrome、Firefox
测试方法Mac 用户可以直接启用进行测试

测试方法

方法 1:浏览器开发者工具

现代浏览器内置了无障碍检查工具:

html
<!-- Chrome DevTools → Elements → Accessibility 面板 -->
<!-- 可以查看无障碍树、ARIA 属性、计算的角色等 -->
html
<!-- Firefox Accessibility Inspector -->
<!-- 工具 → Web 开发者 → 无障碍 -->

方法 2:浏览器内置屏幕阅读器

  • ChromeVox(Chrome 扩展):Chrome 内置的屏幕阅读器
  • VoiceOver(macOS Safari):系统内置,免费使用

方法 3:真实屏幕阅读器测试

步骤操作
1安装屏幕阅读器(NVDA 免费)
2使用 Tab 键从页面顶部开始导航
3使用 heading 快捷键检查标题结构
4使用链接列表检查链接描述
5填写表单,验证标签播报
6使用虚拟光标浏览页面内容
7测试自定义组件的交互行为

方法 4:自动化测试

html
<!-- 使用 axe-core 自动检测 -->
<script src="https://cdn.jsdelivr.net/npm/axe-core@latest"></script>
<script>
  axe.run().then(results => {
    console.log('违规数量:', results.violations.length);
    results.violations.forEach(v => {
      console.log(`[${v.impact}] ${v.description}`);
    });
  });
</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>
    /* 隐藏但可访问的跳过链接 */
    .skip-link {
      position: absolute;
      top: -100%;
      left: 0;
      padding: 0.5rem 1rem;
      background: #0066cc;
      color: white;
      z-index: 100;
    }
    .skip-link:focus { top: 0; }
  </style>
</head>
<body>
  <a href="#main" class="skip-link">跳到主要内容</a>

  <header>
    <h1>产品详情</h1>
    <nav aria-label="面包屑">
      <ol>
        <li><a href="/">首页</a></li>
        <li><a href="/products">产品</a></li>
        <li aria-current="page">无线耳机</li>
      </ol>
    </nav>
  </header>

  <main id="main">
    <section aria-labelledby="product-name">
      <!-- 图片有描述性 alt -->
      <img src="headphones.jpg" alt="黑色无线蓝牙入耳式耳机产品图" />

      <!-- heading 提供标题 -->
      <h2 id="product-name">高端无线蓝牙耳机 Pro</h2>

      <!-- 语义化价格信息 -->
      <p>
        <del>¥499.00</del>
        <strong>¥299.00</strong>
        <span aria-label="六折优惠">6折</span>
      </p>

      <!-- 表单有完整的标签 -->
      <form>
        <fieldset>
          <legend>选择颜色</legend>
          <label>
            <input type="radio" name="color" value="black" checked />
            黑色
          </label>
          <label>
            <input type="radio" name="color" value="white" />
            白色
          </label>
        </fieldset>

        <div>
          <label for="qty">数量</label>
          <input type="number" id="qty" min="1" max="10" value="1"
                 aria-describedby="qty-hint" />
          <span id="qty-hint">最多购买 10 件</span>
        </div>

        <button type="submit">加入购物车</button>
      </form>
    </section>
  </main>

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

注意事项

  1. 不同屏幕阅读器行为不同:同一个页面在不同屏幕阅读器中可能有不同的播报方式
  2. 测试真实的交互流程:不只是"能不能播报",还要测试"用户能否完成任务"
  3. 关注浏览模式:屏幕阅读器在浏览模式和表单模式下的行为可能不同
  4. 考虑阅读速度:冗长的文本会使屏幕阅读器体验变差
  5. 动态内容:确保 Live Region 在各屏幕阅读器中都能正确触发

最佳实践

  • 优先使用语义化 HTML 元素,减少对 ARIA 的依赖
  • 为所有交互元素提供清晰的标签和描述
  • 维护正确的 heading 层级(h1→h2→h3,不跳级)
  • 使用 NVDA + Firefox 或 ChromeVox 进行基础测试
  • 让真实屏幕阅读器用户参与测试
  • 使用浏览器的 Accessibility Inspector 作为日常开发辅助工具
  • 将 axe-core 集成到 CI 流程中作为自动化检查

下一节

继续学习:色彩对比度

参考链接