headers属性必须配th的id才能生效,需确保id真实存在、大小写一致、无空格,多级表头用空格分隔多个id,headers优先级高于scope,axis已弃用。

headers属性必须配th的id才能生效
写了 headers="name" 却没读屏效果?八成是 <th> 没加 <code>id,或者 id 值拼错了。它只认 DOM 中真实存在的、大小写完全一致的 id 字符串,不认 class、不认文本内容、不认 colspan 推断。
常见踩坑点:
-
<th>姓名</th>没设id,光在<td headers="name"> 里写,等于白写 <li> <code><th id="Name">姓名</th>和<td headers="name"> 因大小写不一致,关联断裂 <li> <code><th id="name dept">部门</th>含空格——HTML 中id不允许含空格,这个id实际无效
多级表头必须用空格分隔多个id
一个 <td> 同时属于「年份」「季度」「地区」三个维度时,<code>headers 的值必须是 "year q1 beijing" 这种空格分隔形式,不是逗号、不是引号、不是数组写法。
浏览器只把整个属性值当字符串切分,只认空格为分隔符。对应结构必须保证每个 id 都真实存在且唯一:
立即学习“前端免费学习笔记(深入)”;
<th id="year" rowspan="2">年份</th> <th id="q1" colspan="3">Q1</th> <th id="beijing">北京</th> <td headers="year q1 beijing">120</td>
漏掉任一 id,或拼错一个,屏幕阅读器就只读出部分上下文,甚至完全跳过表头。
headers和scope同时存在时,headers会覆盖scope
WAI-ARIA 规范明确:只要 headers 存在,scope 就被忽略。很多开发者误以为两者能互补,实际是互斥。
简单表(单层行列)用 scope 更轻量;一旦出现 rowspan、colspan 或多级标题,headers 才是唯一可靠手段。别为了“兼容旧读屏器”乱加 scope——NVDA、VoiceOver、JAWS 2022+ 全都支持 headers,且更准。
动态渲染时尤其要注意:<th id="name"> 必须在 <code><td headers="name"> 渲染前已挂载到 DOM,否则首次无障碍树未建立关联,且没有任何报错提示。
<h3>别用axis,它已被HTML5正式弃用</h3>
<p><code>axis 在所有现代可访问性链路中都不起作用。W3C 明确标记为过时,Chrome/Firefox/Safari 虽不报错,但 NVDA、VoiceOver、JAWS 全部忽略它。
更麻烦的是:axis 值无校验,axis="sales,q1" 和 axis="sales q1" 都算合法,但辅助技术根本无法解析。如果你看到老项目里还留着 axis,直接删掉,换成 headers 或 aria-labelledby。
真正难的不是查文档写对 id 和 headers,而是在每次敲下 <td> 时,下意识确认:它要绑定的每一个 <code>id,是否已在 DOM 中真实存在、拼写正确、且未被重复使用。



















