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

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











