表格必须用语义化标签确保无障碍:caption需为table首个子元素且具业务含义;th必须声明scope属性;复杂表格用id+headers显式绑定;筛选行禁用role属性。

caption 必须紧贴 <table> 且不能空泛
屏幕阅读器进入表格时,第一个播报的就是 <caption> 内容。如果它被塞进 <thead> 里,或者写成 <caption>数据表</caption>,用户根本不知道这表格是干啥的。
正确做法是让它成为 <table> 的首个子元素,内容需具业务指向性:
-
<table><caption>2026年Q1前端班学员考核成绩</caption>...✅ -
<table><thead><caption>...</caption></thead>...❌(位置错) -
<caption>表格</caption>或空 caption ❌(语义失效)
scope 属性不是可选,而是强制声明
没写 scope 的 <th>,对屏幕阅读器来说只是加粗文本,不带任何行列归属关系。用户听到“张三”“32”“上海”,但完全不知道哪个是姓名、哪个是年龄、哪个是城市。
必须按规则显式标注:
立即学习“前端免费学习笔记(深入)”;
-
<th scope="col">姓名</th>—— 只能出现在<thead>,管整列 -
<th scope="row">张三</th>—— 只能放在<tbody>每行第一个<th>,不能塞进<td> - 无表头的列(如操作按钮列)别用
<th>,直接用<td>
复杂表格必须用 id + headers 显式绑定
一旦出现 rowspan、colspan 或多级表头,scope 就失效。屏幕阅读器无法自动推断一个 <td> 同时属于哪几个表头,必须靠 headers 手动指明。
实操步骤很明确:
- 给每个关键表头加唯一
id:<th id="name-header" scope="col">姓名</th> - 在对应数据单元格上写
headers,多个用空格分隔:<td headers="name-header dept-header">张三</td> - 别依赖视觉对齐——DOM 顺序乱了也没关系,只要
headers值写对,播报就准
筛选行千万别给 <tr> 加 role
很多人为了“增强语义”,给筛选行的 <tr> 加 role="search",结果触发 aria-requires-children 报错。根本原因是破坏了 <tr> 的原生表格角色,让屏幕阅读器把它从表格结构中剥离。
正确做法极其简单:
- 保留原生
<tr>结构,不加任何role - 把
<input type="search">放进<td>里 - 每个输入框配
aria-label(如aria-label="按姓名筛选"),或用aria-labelledby指向对应列头id
真正难的不是查文档写对 scope,而是在每次敲下 <th> 时,下意识问一句:“它管的是行,还是列?”这个条件反射比任何自动化工具都管用。



















