讲解

无障碍(Accessibility,常缩写为 a11y——a 和 y 之间有 11 个字母)是让残障人士也能正常使用网页的实践:视障用户靠屏幕阅读器「听」页面,运动障碍用户只靠键盘操作,听障用户依赖字幕。这不是少数人的小众需求——临时受伤、强光下看不清屏幕、嘈杂环境里看视频,人人都会遇到「类残障」场景。好消息是:HTML 写对了,无障碍就完成了一大半,因为语义化标签自带辅助技术需要的信息。

最容易落地的四条规则。第一,图片必须有合适的 alt:内容图认真描述,装饰图留空 alt,这是读屏用户获取图像信息的唯一通道。第二,表单控件必须关联 <label>,读屏软件念出「邮箱,编辑框」用户才知道该填什么;光秃秃的输入框只会被念成「编辑框」。第三,标题层级连续(h1 起、不跳级),读屏用户靠标题列表浏览页面,跳级等于目录缺页。第四,<html lang="zh-CN"> 让读屏软件选对发音引擎,标错语言的中文会被念成天书。

进阶两条。键盘可达性:只用 Tab 键能否走遍页面所有可交互元素、能否看清焦点在哪?链接、按钮、表单控件天生可聚焦,div 模拟的按钮则完全到不了——又一个「用语义标签」的理由;也不要用 outline: none 把焦点框抹掉而不提供替代样式。ARIA(如 rolearia-label)是给自定义组件补语义的补丁,第一原则是「能用原生 HTML 就不用 ARIA」:<button> 自带按钮语义与键盘行为,<div role="button"> 则需要你手动补齐一堆特性。最后,正文文字与背景的对比度应达到 WCAG 的 4.5:1,浅灰小字是低视力用户的第一杀手。

示例

<!-- 跳转链接:键盘用户按 Tab 第一站,直达正文 -->
<a class="skip-link" href="#main">跳到主要内容</a>

<header>
  <nav aria-label="主导航">
    <ul>
      <li><a href="/">首页</a></li>
      <li><a href="/docs">教程</a></li>
    </ul>
  </nav>
</header>

<main id="main">
  <h1>无障碍基础</h1>

  <!-- 图片:内容图描述内容,装饰图空 alt -->
  <img src="diagram.png" alt="流程图:用户请求经 CDN 到达服务器再返回页面" width="640" height="360" />
  <img src="divider.svg" alt="" width="600" height="20" />

  <!-- 表单:每个控件都有 label -->
  <label for="email">邮箱</label>
  <input type="email" id="email" name="email" />

  <!-- 图标按钮:没有可见文字时用 aria-label 补名 -->
  <button aria-label="关闭对话框">✕</button>
</main>

跳转链接平时隐藏、聚焦时显示:

.skip-link {
  position: absolute;
  left: -9999px;
}
.skip-link:focus {
  left: 8px;
  top: 8px;
}

常见坑

  • 用 div 模拟按钮:不可聚焦、无键盘事件、读屏不识别,要手动补 role、tabindex、键盘监听一大串。一个 <button> 全解决。
  • outline: none 一删了之:焦点框消失后键盘用户完全迷路。嫌默认焦点框丑就自定义更醒目的 :focus 样式,而不是删除。
  • 重复废话的 alt:alt="图片:一只猫" 里的「图片」是噪音,读屏软件本来就会报「图像」。直接描述内容即可。
  • aria-label 覆盖可见文字:有可见文字的按钮优先让文字本身达意;aria-label 会完全替代可见文字被朗读,两边对不上就麻烦了。

小结

语义化 HTML 是无障碍的地基;alt、label、标题层级、lang 是四大基本功;保证键盘可达、焦点可见;ARIA 是补丁,原生元素永远优先。下一章是全套教程的收尾:HTML 最佳实践清单。