08无障碍访问
无障碍(a11y)= 让所有人都能用上你的网页,包括看不见屏幕的人、 用不了鼠标的人。好消息是:做好它基本不需要额外成本, 大多数时候只需要一件事——用对标签。
一、什么是无障碍(a11y)
a11y 是 accessibility 的数字缩写:首字母 a 和尾字母 y 之间 夹着 11 个字母,写全太累,于是大家约定俗成叫它 a11y(读作 "ally",盟友——挺贴切)。
谁需要无障碍?远比你想象的多:
最后这类「情境障碍」指向一个重要观点:无障碍让所有人受益。 城市里的轮椅坡道,推行李箱的、推婴儿车的、骑滑板车的都在用—— 这就是著名的「路缘坡效应」:为少数人做的设计,最后方便了每一个人。
二、语义化是无障碍的地基
还记得第 06 课的语义化吗?它就是无障碍的地基。屏幕阅读器靠
<nav>、<main>、标题层级这些语义标签
「读」出页面结构:用户可以直接说「跳到导航」「跳到正文」
「列出所有标题」。如果全页都是 div,速读员拿到的是一锅粥——每一口都一样,没有目录可跳。
| 页面区域 | div 汤读起来 | 语义化读起来 |
|---|---|---|
| 导航区 | 「分组……一堆链接」(不知道是导航) | 「导航,地标」→ 可一键直达 / 跳过 |
| 主内容 | 和侧栏、页脚混在一起,无从分辨 | 「主要内容,地标」→ 说「跳到正文」就到 |
| 标题 | 和普通文字一个待遇,没有层级 | 「标题,级别 2」→ 可列出全页标题当目录 |
| 页脚 | 「分组……版权信息」 | 「内容信息,地标」 |
<header> <nav> <main>
<footer> 和连续的标题层级,无障碍就完成了一大半。三、alt:图片的「语音替身」
速读员看不见图片,它只念 <img> 的 alt 属性——
alt 就是图片的「语音替身」。写 alt 记住三原则:
- 信息图写清内容:图片想传达什么就写什么,如「2026 上半年学习时长柱状图,6 月最高」。
- 装饰图写空 alt:纯好看的花边、分隔线写
alt="",速读员会直接跳过,不打扰用户。 - 别以「图片」二字开头:速读员自己会报「图像」,你再写「图片:一只猫」就成了「图像 图片 一只猫」。
alt 还有一个隐藏福利:图片加载失败时,浏览器会把 alt 文字显示在占位框里。 网速差、图床挂了的时候,用户也不至于面对一个莫名其妙的裂图图标。
alt 改成你写的描述,看占位框文字跟着变;再把它改成 alt="",看它「隐身」四、label:表单的无障碍关键
输入框旁边的说明文字,如果只是孤零零一段文本,速读员念到输入框时只会说
「编辑框」——填什么?全靠猜。<label> 就是文字和输入框之间的
「红绳」,两种牵法:
牵上红绳的好处是双份的:速读员会先念「邮箱」再念「编辑框」; 更妙的是,点击 label 文字本身就能聚焦输入框—— 点一大块文字比点一个小框容易得多,手指粗的、手抖的、在地铁里晃的用户全都受益。
五、键盘导航:Tab 键走天下
很多人从头到尾只用键盘:运动障碍用户、笔记本触摸板坏了的人、追求效率的程序员。
他们的全部操作就是 Tab 前进、Shift+Tab 后退、Enter 确认。
好消息是,原生可交互元素——<a>、<button>、
<input>——天生就能被 Tab 到,不用你做任何事。
| 写法 | 效果 | 建议 |
|---|---|---|
| (不写) | 原生可交互元素自动可 Tab;div / span 不可 Tab | 首选:能用 <button> 就别用 div 冒充 |
| tabindex="0" | 让任何元素(如 div)进入 Tab 顺序,位置按文档流 | 万不得已才用;用了还得自己补键盘事件和焦点样式 |
| tabindex="-1" | 不能 Tab 到,但可被脚本 focus()(如弹窗标题) | 配合 JS 做焦点管理时用 |
| tabindex="2"(大于 0) | 强行插队,打乱自然顺序 | 别用:Tab 顺序会乱成一锅粥 |
焦点圈(focus outline)是键盘用户的「鼠标指针」——
它告诉用户「你现在在哪」。:focus-visible 只在键盘聚焦时显示焦点圈,
鼠标点击不显示,兼顾美观与可用。
tabindex="0" 的 div;按 Shift+Tab 则倒着走outline: none 又不给替代样式——
键盘用户会瞬间在你的页面里「失明」,不知道焦点在哪。要么留着默认焦点圈,
要么像上面实验一样换成更醒目的自定义 :focus-visible 样式。六、aria-*:给机器的补充说明
aria-* 系列属性是专门写给辅助技术看的「补充说明」,
普通用户完全看不见。但请牢记第一原则:
能用语义标签解决,就别用 aria——
一个原生 <button> 胜过一百行 aria 补丁。
aria 只用于语义标签覆盖不到的角落。
| 属性 | 作用 | 典型场景 |
|---|---|---|
| aria-label | 给元素一个文字名字,只有机器读得到 | 纯图标按钮(一个 ✕ 没有文字):aria-label="关闭" |
| aria-hidden="true" | 对读屏隐身,就当它不存在 | 纯装饰图标、分隔花纹,别让速读员念出「星星 星星 星星」 |
| aria-describedby | 指向一段补充说明的 id | 密码框关联「至少 8 位,含字母数字」的提示 |
| role | 告诉机器「这玩意儿是什么角色」 | 谨慎用:多数语义标签自带 role,手抖写错比不写更糟 |
aria-label 删掉,它在读屏里就只剩一声「按钮」七、颜色对比度:别把浅灰当正文色
浅灰字配白底,设计稿上很「高级」,阳光下、老花眼里就是一片空白。 国际上用 WCAG 标准给对比度划了红线——对比度是个比值, 最黑配最白是 21:1,同色是 1:1:
| 文字类型 | 最低对比度 | 说明 |
|---|---|---|
| 正文、普通文字 | ≥ 4.5 : 1 | 绝大多数文字按这条执行 |
| 大字号(≥24px 或 ≥19px 加粗) | ≥ 3 : 1 | 字大就自带清晰度,要求放宽 |
| 纯装饰、禁用态 | 无要求 | 不传信息的元素不受限 |
常见翻车现场:浅灰字白底(#CCC 配 #FFF,对比度约 1.6:1)、 白字浅黄底、品牌色直接当正文色。下面的实验让你亲手感受差距:
.bad-a 的 color 改成 #8F3A26,看它瞬间清晰;再把 .good-a 改成 #C08A3E,体验「设计稿高级、阳光下抓瞎」八、小结
- a11y = accessibility(a 和 y 之间 11 个字母);无障碍受益的是所有人——路缘坡效应。
- 屏幕阅读器是「读屏的速读员」,语义化标签就是它唯一的眼睛:地标 + 标题层级 = 可跳读的目录。
alt是图片的语音替身:信息图写清内容、装饰图alt=""、别用「图片」开头;加载失败时它还会兜底显示。<label>用 for+id 或包裹式牵上红绳:读屏能念、点文字也能聚焦输入框。- 原生可交互元素天生可 Tab;
tabindex只用 0 和 -1,别用大于 0 的值;焦点圈是键盘用户的鼠标指针,别随手outline: none。 - aria 第一原则:能用语义标签就不用 aria;常用三件套 aria-label(图标按钮命名)、aria-hidden(装饰隐身)、role(谨慎用)。
- 正文对比度 ≥4.5:1,大字号 ≥3:1——设计好看不等于看得清。
<img> 补上合格的 alt(装饰图写空);
③ 检查所有表单控件都有关联的 <label>,点文字验证能聚焦。