aria-label完全覆盖元素内文本,仅读指定字符串;aria-labelledby引用页面中真实ID的可见文本,支持多ID拼接朗读;二者不可共存,aria-labelledby优先级更高。

aria-label 会完全覆盖元素内所有文本内容
只要写了 aria-label,屏幕阅读器就只读这个字符串,不管里面有没有文字、图标或子元素。比如 <button aria-label="关闭">×</button>,读出来就是“关闭 按钮”,不会提“乘号”或“叉号”。
常见错误是给已有可见文字的按钮硬加 aria-label,比如 <button aria-label="删除">删除</button>——看似没坏,但某些读屏器会重复播报,或者在多语言环境下导致文案维护脱节。
适合场景:<button><svg></svg></button> 这类纯图标按钮;动态生成但无 DOM 文本的控件(如表格行操作按钮)。
aria-labelledby 必须引用真实存在的 ID,且支持拼接
aria-labelledby 不是写字符串,而是指向页面里已有的文本节点。ID 不存在、拼错、或目标元素不可访问(比如 display: none 或 aria-hidden="true"),它就静默失效——不报错,也不读。
它支持空格分隔多个 ID,按顺序拼接朗读,比如 aria-labelledby="icon-desc name-cell status-badge" 会读成“编辑 张三 已保存”。
适合场景:模态框关闭按钮复用标题(<h2 id="modal-title">用户设置</h2> + <button aria-labelledby="modal-title"></button>);图表旁有独立标题和说明;表单字段上方有视觉分离的 <h3> 标签但无法用 <label for> 关联。
两者不能共存,aria-labelledby 优先级更高
如果同时写了 aria-label 和 aria-labelledby,浏览器会忽略 aria-label,只处理 aria-labelledby。这不是兼容性差异,而是规范强制行为。
实际调试中常遇到开发者为“保险起见”两个都写,结果 aria-labelledby 指向的 ID 不存在,又没 fallback,整个可访问名称就空了。
检查方法:用 Chrome DevTools 的「Accessibility」面板,看「Name Computation」一栏是否显示有效来源;别依赖肉眼检查 HTML 属性是否存在。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
图标按钮必须把 aria-label/aria-labelledby 写在可交互容器上
<svg aria-label="下载"></svg> 是无效的——<svg> 默认不是焦点可抵达的控件,读屏器直接跳过。
正确做法是把属性写在 <button> 或带 role="button" 的外层容器上:<button aria-label="下载"><svg></svg></button>。
如果用了 <div onclick> 模拟按钮,除了 aria-label,还必须加 role="button" tabindex="0",并手动监听 Space 和 Enter 键事件——否则键盘用户根本无法触发。
立即学习“前端免费学习笔记(深入)”;
最常被漏掉的是 ID 的存在性验证和键盘交互配套。写完aria-labelledby 后不检查目标元素是否渲染、是否可见、是否被 aria-hidden 封锁,等于白写;给伪按钮加了 aria-label 却忘了 tabindex 和空格键支持,等于只做了一半。


















