headers 属性是解决复杂表格屏幕阅读器语义丢失的唯一可靠手段,需配合 th 的 id 使用,且 id 必须唯一、命名严格一致、空格分隔多个有效值,不可与 scope 混用。

headers 属性是解决复杂表格屏幕阅读器语义丢失的唯一可靠手段——当表格出现 rowspan、colspan 或多级表头时,仅靠 scope 已经失效,必须用 headers 显式绑定。
headers 必须配合 th 的 id 才能生效
写了 headers="year q1" 却没效果?大概率是 <th> 根本没设 <code>id,或者 id 拼错、大小写不一致、含空格或特殊字符。
-
<th>年份</th>不加id,<td headers="year"> 就是无效引用 <li> <code><th id="Year">年份</th>和<td headers="year"> 因大小写不匹配而断连 <li><code><th id="q1 sales"> 是非法 ID(含空格),浏览器不认,<code>headers查不到目标 - 每个
id必须在当前<table> 内唯一存在,不能跨表复用 <h3>多维表头必须用空格分隔多个真实 <code>id一个
<td> 同时属于「地区」「季度」「指标」三个维度,就得让 <code>headers精确列出对应th的全部id,不能用逗号、引号或换行。- 正确:
<td headers="region q1 metric">华东 Q3 销售额 <li>错误:<code><td headers="region,q1,metric">(逗号分隔 → 读屏器只认第一个) <li>错误:<code><td headers="'region' 'q1' 'metric'">(引号包裹 → 整个字符串被当做一个 ID) <li>漏掉任一 <code>id,屏幕阅读器就只播报部分上下文,比如只读“Q3”,不提“地区”和“指标” - 简单表(单层行列)→ 用
scope="col"/scope="row"更轻量 - 复杂表(跨行/跨列/多级)→ 全量切换到
headers+id,别留scope - 动态渲染时,
<th id="xxx"> 必须在 <code><td headers="xxx"> 渲染前挂载到 DOM,否则首次无障碍树无法建立关联 <p>真正难的不是写对语法,而是每次写 <code><th> 时,下意识确认它有没有 <code>id、名字是否和headers值严格一致——这个习惯比任何自动化检测都管用。
headers 和 scope 不能混用,且会互相覆盖
WAI-ARIA 规范明确:只要
headers存在,scope就被忽略。试图“兼顾兼容性”同时写两者,反而导致现代读屏器(NVDA/JAWS/VoiceOver)行为不可预测。立即学习“前端免费学习笔记(深入)”;
- 正确:



















