headers不是“建立关联”,而是声明归属——它只告诉屏幕阅读器“这个属于哪些”,不触发js行为、不改变dom、不影响样式;必须指向同表内已定义的id,大小写严格匹配,多级表头需逐级绑定,动态渲染时须确保先于挂载。

直接说结论:headers 不是“建立关联”,而是**声明归属**——它只告诉屏幕阅读器“这个 <td> 属于哪些 <code><th id>”,不触发任何 JS 行为、不改变 DOM、不影响样式。想靠它实现联动或筛选,必须配 JS。
<h3>headers 必须指向同表内已定义的 <code>id
这是最常断连的点:写了 headers="year q1",但 <th id="year"> 根本没写,或者写在了另一个 <code><table> 里,甚至用了 <code>class="year" 代替 id。
<th> 必须显式带 <code>id,且值全小写、无空格、无特殊字符(id="Q1-2024"合法,id="Q1 2024"非法)<td headers="year q1"> 中的每个 ID 都得在当前 <code><table> 内真实存在,大小写严格匹配 <li>动态插入表头时,漏掉 <code>el.id = "q1"是高频失误;服务端渲染后客户端又改 ID,也会导致首次无障碍树失效- 正确:
<th id="year">年份</th>,<th id="q1" headers="year">Q1</th>,<td headers="q1 beijing">120</td> - 错误:
<td headers="year q1 beijing"> —— 会导致读屏器重复播报“年份 Q1 120, Q1 Q1 120” <li> <code>headers值必须用空格分隔,headers="year,q1"或headers=""year" "q1""全无效 <th id="hidden-header"> 被 <code>display: none隐藏,但仍在 DOM 中——读屏器会读出它,造成冗余;应移除 ID 或改用aria-label- 表格由 React/Vue 渲染,
<th id> 在 <code><td headers> 挂载之后才生成,首次无障碍树无关联 <li>混用了 <code>scope和headers,调试时误以为 scope 还起作用(实际headers优先级永远更高,scope被完全忽略)
多级表头怎么写 headers 值
不是把所有父级 id 全塞进去,而是按语义层级逐级绑定。比如“年份 → 季度 → 城市”,底层 <td> 只需直接关联最近一级的 <code><th id="beijing">,而 <code><th id="q1"> 自己再用 <code>headers="year" 关联上层。
为什么写了 headers 还被 Lighthouse 报错
报 “<td> missing header” 几乎从不是语法问题,而是 DOM 状态不一致:
<ul>
<li>ID 拼错一个字母(<code>id="sales" vs headers="sale")
真正容易被忽略的是:headers 的生效前提是“DOM 可达”——ID 必须在 <td> 渲染完成前就存在于同一文档流中,哪怕它视觉上不可见,只要节点还在,语义就成立。</td>
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











