先记住这个答案
简单的二维表格用 <th scope="row">、<th scope="col"> 已足够。财务报表若有“2026 年 → 第一季度 → 收入”多层表头,一个数字可能要同时关联几个标题;这时给每个 <th> 唯一 id,在数据格的 headers 属性里用空格列出对应 ID。辅助技术就有机会按这些关系解释数值,而不是只读一个孤立数字。
- 每个关联表头需要唯一
id headers列出多个表头 ID- 简单行列表头优先用
scope - 关系必须与实际数据含义一致
一格数据对应多个标题
报表中的 120 万元如果只听到数字,用户无法判断它属于哪个地区、哪个季度和哪项指标。显式关联让数据的语境跟随单元格。
<table>
<caption>季度收入</caption>
<tr><th id="region">地区</th><th id="q1">第一季度</th></tr>
<tr><th id="north">北区</th><td headers="north q1">120 万元</td></tr>
</table>这个简化例子里,120 万元关联“北区”和“第一季度”。实际多层表头还可加入年份、收入类型等 ID,数据格的 headers 按需要列出全部相关表头。
示例很简单,也能用 scope 表达;它用来展示 headers 的基本语法。只有结构确实复杂时才值得逐格写显式关联,否则维护成本更高。
假如表格又加了一层“收入”表头,并给它 id="revenue",对应数据格的属性就可以写成 headers="north q1 revenue"。三个 ID 都必须指向这张表里真实存在的 <th>;把可见文字直接塞进 headers,或让复制行复用同一 ID,都建立不了可靠关系。
维护表头关系要跟数据同步
表格列被动态隐藏、重新排序或由接口生成时,ID 和 headers 也要一起更新。复制一个表头 ID 到多格,或者删了表头却保留引用,会让读屏得到错误上下文。
设计复杂数据表时,先确认是否能拆成几张更简单的表。若必须保持交叉结构,写完后用辅助技术实际逐格导航,检验读出的行列标题是否符合数据含义。
例如同一行既有“收入”又有“成本”,复制整列时若只更新数字、不更新对应 headers,辅助技术会把成本读成收入。数据表由模板生成时,最好从列定义同时生成可见表头、表头 ID 和单元格引用,减少手写字符串造成的错配。
headers 属性不是跨表引用工具:关联的表头要属于同一张表。多个表格都把列头写成 id="q1" 也会破坏整个文档的 ID 唯一性。命名时可带上表格标识,再用实际生成的 ID 填入数据格。
容易答错的地方
- 把
headers写成标题文本 - 属性值应是相关
<th>的 ID,以空格分隔。 - 只因有两行表头就机械加大量 ID
- 若
scope能清楚表达关系,简单方案更易维护;显式关联用于复杂关系。
面试官还会怎么问?
一个 <td> 能关联三个表头吗?
能。在 headers 中写三个有效表头 ID,以空格分隔。
id 可在不同表头重复吗?
不应重复。文档中的 ID 必须唯一,否则引用关系可能含糊或错误。
为什么不只靠视觉合并单元格?
视觉位置不能保证辅助技术知道每格关联哪个上层标题,需要语义关系。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。