HTML 可访问性(A11y)清单:让屏幕阅读器读懂你的页面
照着这份清单改一遍,你就能让屏幕阅读器用户顺畅地读完、点完你的页面,而不是听到一堆「链接 链接 链接」。
可访问性(Accessibility,简称 A11y,因为 accessibility 首尾字母之间有 11 个字母)不是额外加的功能,而是把 HTML 写对。下面按从骨架到细节的顺序列一遍,每一项都给出具体的写法。
第一步:用语义标签搭出页面骨架
屏幕阅读器用户最常用的操作是按快捷键在「地标(landmark)」之间跳转。你只要用对标签,这些地标就自动存在了:
<header>站点头部</header>
<nav aria-label="主导航">导航</nav>
<main>
<article>正文内容</article>
<aside>侧栏</aside>
</main>
<footer>页脚</footer>
一个页面只放一个 `<main>`,它对应屏幕阅读器里的「主内容」跳转键。`<nav>` 多于一个时(比如主导航 + 页脚导航),用 `aria-label` 区分:`aria-label="主导航"`、`aria-label="页脚导航"`。
注意:不要为了布局方便用 `<div class="header">` 代替 `<header>`。CSS 里写 `div.header` 还是 `.header` 视觉上一模一样,但屏幕阅读器拿不到任何信息。
第二步:标题层级别跳级
`<h1>` 到 `<h6>` 是屏幕阅读器用户浏览长文的主要导航方式,很多人就是靠「按 H 键逐个跳标题」来扫读的。
规则只有两条:页面只保留一个 `<h1>`;层级从 h1 往下依次递增,不要从 h2 直接跳到 h4。
如果某个区块视觉上不需要大字号标题,用 CSS 把它视觉隐藏(或缩小),而不是把标签降级成 `<div>`:
.visually-hidden {
position: absolute; width: 1px; height: 1px;
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
第三步:图片的 alt 分三种情况写
<!-- 1. 有信息量的图:描述内容 -->
<img src="chart.png" alt="2024 年 Q1 到 Q4 营收逐季上升,Q4 达 320 万">
<!-- 2. 纯装饰图:给空 alt,别省略 -->
<img src="line.svg" alt="">
<!-- 3. 图片本身就是链接:描述去向,不是描述图 -->
<a href="/home"><img src="logo.png" alt="返回首页"></a>
注意:`alt=""`(空值)和完全不写 `alt` 是两回事。不写,部分屏幕阅读器会把文件名念出来,比如「logo-2x-final-真的最终版.png」。
第四步:表单控件必须挂 label
三种绑定方式,任选一种:
<!-- 方式一:for / id 关联(推荐) -->
<label for="email">邮箱</label>
<input id="email" type="email" required>
<!-- 方式二:包起来 -->
<label>邮箱 <input type="email"></label>
<!-- 方式三:视觉上不需要 label 时 -->
<input type="search" aria-label="站内搜索">
只写 `placeholder` 不算 label——placeholder 在输入时就消失了,而且对比度通常不达标。错误提示也别只靠红色边框,加一行 `aria-live="polite"` 的文本区,或在 input 上关联 `aria-describedby="err-1"`。
第五步:能点的东西就用 button 或 a
`<div onclick="...">提交</div>` 是最常见的坑:它拿不到键盘焦点,回车和空格也没反应,屏幕阅读器只会念成「提交 文本」。
- 会跳转/换页面 → `<a href="...">`
- 触发动作(提交、展开、删除)→ `<button type="button">`
用 `<button>` 后,焦点、回车、空格、禁用态全是浏览器送的。展开折叠类控件补个状态:
<button type="button" aria-expanded="false" aria-controls="panel1">展开详情</button>
<div id="panel1" hidden>...</div>
JS 里切换 `aria-expanded` 的 true/false,同时切 `hidden` 属性。
第六步:ARIA 的第一条规则是「别用 ARIA」
能用原生标签解决的,就别加 role。原生 `<button>`、`<input type="checkbox">`、`<select>` 自带完整语义和键盘行为,`role="button"` 只是贴了个标签,行为还得你自己补。
少数必须用 ARIA 的场景:动态提示(`aria-live="polite"`)、图标按钮的 `aria-label`、模态框焦点约束。用错了反而比不用更糟——比如给 `<div>` 加 `role="button"` 却不写 tabindex 和键盘事件,等于告诉屏幕阅读器「这是个按钮」然后按下去没反应。
第七步:键盘走一遍,焦点看得见
按 Tab 键从页面顶部一直走到页脚,检查三件事:
- 焦点顺序和视觉顺序一致;
- 每个可操作元素都有明显的焦点框——别写 `outline: none` 就完事,要换成 `:focus-visible { outline: 2px solid #1a73e8; outline-offset: 2px; }`;
- 内容多的站点,在 `<body>` 开头加个跳转链接:
<a href="#main" class="visually-hidden">跳到主内容</a>
模态框打开时给容器 `tabindex="-1"` 并 `.focus()`,关闭时焦点还给触发按钮。
第八步:颜色对比度达标
正文文本对比度至少 4.5:1;18pt 以上或 14pt 加粗的大字至少 3:1。按钮、图标、输入框边框这类界面元素至少 3:1。
不要只用颜色传达信息——「必填项标红」之外再加个星号或文字说明,色盲用户看不出红绿差别。
第九步:用工具自查
浏览器装 axe DevTools 扩展,打开页面点扫描,它会按严重程度列出问题并给出修复代码;Lighthouse 的 Accessibility 面板可以跑个总分;最后用真实屏幕阅读器过一遍:Windows 用 NVDA(免费),macOS 用自带的 VoiceOver(`Cmd + F5` 开启,`Ctrl + Option + 方向键` 浏览),手机用 VoiceOver / TalkBack。
注意:自动化工具大约只能查出 30%–40% 的问题,像「alt 写得不准确」「焦点顺序不合理」这类必须人工判断,别看到分数 100 就收工。
小结
- 语义标签搭骨架:`header` / `nav` / `main` / `footer`,一页一个 `main`
- 标题不跳级,一页一个 `h1`
- 图片 alt 三分法:有信息就描述、装饰给空值、是链接就描述去向
- 表单控件必须有 label,错误提示别只靠颜色
- 能点的用 `button` 或 `a`,不要 `div`
- ARIA 能不用就不用,用了要配套补行为
- 键盘全流程走一遍,焦点框必须可见
- 正文对比度 ≥ 4.5:1,界面元素 ≥ 3:1
- 工具查 + 真人屏幕阅读器测,两者都不能省
转载请注明出处,版权归原作者所有。
星耀SVIP
管理员
黑卡会员





