alt和aria-label用错会导致屏幕阅读器误读或跳过内容;必须为img设alt,图标按钮需role="button"配合aria-label;aria-label不能替代label;svg需role="img";tabindex值错误会破坏导航顺序;aria属性须与交互逻辑一致。

alt 和 aria-label 用错地方,屏幕阅读器就“听不懂”
图片没写 alt,图标按钮只加 aria-label 不配 role="button",这两类错误最常见——屏幕阅读器要么跳过、要么读出一堆无意义的文件名或空格。
-
alt是<img>的强制属性:装饰图必须写alt="",内容图要能独立传达信息(比如“登录按钮图标”不如“使用微信扫码登录”) -
aria-label不能替代<label></label>:表单控件用了aria-label,校验逻辑和屏幕阅读器焦点行为可能断裂;正确做法是显式用<label for="id"></label>或包裹<input> - SVG 内联时,
<svg></svg>默认无语义,必须加role="img"+aria-label,否则读不出任何内容
tabindex 不是“加了就能聚焦”,顺序错了反而害人
tabindex="0" 让元素进键盘流,tabindex="-1" 只支持 JS 主动聚焦,但很多人误设 tabindex="1" 或更高值,直接打乱自然导航顺序,键盘用户得反复按 Shift+Tab 才能绕回来。
- 仅对非可交互原生元素(如
<div> 模拟按钮)用 <code>tabindex="0";原生<button></button>、<a></a>不用额外加 - 禁用状态的控件(
disabled或aria-disabled="true")再设tabindex="0"无效,会被浏览器自动忽略 - 别给纯文本块(如
<p></p>)加tabindex="0":键盘用户被迫“穿过”几十个无操作节点,体验极差 - 优先用原生语义标签:
<nav></nav>、<main></main>、<fieldset></fieldset>、<ul role="list"></ul>(仅当 CSS 重置了默认 list-style 且需语义强化时才加) -
role="tooltip"必须配合aria-describedby指向真实 DOM 节点,且该节点要设aria-hidden="true"初始隐藏;靠title属性撑场面,移动端基本失效 -
aria-live值选"polite"还是"assertive"看内容紧急程度:表单错误提示用polite,系统级告警才用assertive,乱用会打断用户当前操作 -
lang必须声明在根节点,子语言切换用局部lang="en",比如引文或代码片段 -
title不该承载关键信息:它不被所有屏幕阅读器朗读,也不响应键盘焦点,重要提示一律走aria-describedby或独立提示区域 - 多语言混合页面中,
lang和dir(rtl/ltr)要同步设置,否则阿拉伯语文字可能左右颠倒
role 和 aria-* 属性不是补丁,用错比不用更糟
ARIA 是补充语义的工具,不是重写语义的捷径。用 role="button" 包裹 <div> 却不处理 <code>Enter/Space 键事件,或给 <nav></nav> 加 role="navigation",都是典型冗余甚至冲突操作。
lang 和 title 看似简单,但漏掉就断上下文
缺失,屏幕阅读器可能用英文引擎读中文,发音怪异;title 当 tooltip 用,鼠标悬停才显示,键盘用户根本看不到——它只是辅助说明,不是交互入口。
复杂点在于:可访问性不是属性堆砌,而是语义链的连贯性。一个 aria-controls 指向的 ID 不存在,或 aria-expanded 和实际 DOM 显示状态不一致,辅助技术就会彻底“迷路”。检查时别只跑 Lighthouse,务必手动用键盘 Tab 导航 + VoiceOver/TalkBack 实时听一遍流程。











