应将多级分组拆分为多个独立并用包裹,每个表格配完整/、及显式scope属性;键值对改用而非单列表格。

单张 <table> 套多级分组会破坏屏幕阅读器上下文识别
<p>当把“住院费用”“护理机构服务”“终身储备日规则”等逻辑独立的区块硬塞进同一张 <code><table>,哪怕用了 <code><th colspan="4">Hospitalization</th> 或 CSS 视觉分隔,屏幕阅读器仍只将其视为普通行——它无法推断后续 5 行数据都属于这个标题。用户逐单元格导航时,听到的是“First 60 days, $1,600”,却不知道这属于哪一类费用。
根本问题在于:<table> 的语义模型只支持单层行列关系,没有“子区域”概念。辅助技术不会主动将视觉上相邻的 <code><tr> 归属到上方某个 <code><th> 下,除非你显式建立结构化隶属关系。
<ul>
<li>用 <code>aria-describedby 指向分组标题 ID 是常见补救手段,但仅附加一次描述文本,不随焦点移动重复播报,上下文极易丢失
headers 属性虽能绑定多个表头 ID,但需为每个 <td> 手动维护 ID 列表,大型表格易出错且不可维护
<li>嵌套 <code><table> 不解决本质问题,反而增加 DOM 深度和 AT 解析负担
<h3>拆成多个独立 <code><table> + <code><section></section> 是最健壮的方案
把每个业务分组(如 “Hospitalization”)封装为一个完整、自洽的 <table>,并用 <code><section aria-labelledby="sec-id"></section> 包裹,是 WCAG 2.2 和主流 AT(NVDA/JAWS)验证过的最佳实践。
这样做的直接效果是:每个 <table> 都有自己完整的 <code><thead>/<code><tbody>、<code><caption></caption> 和 scope 关联,无需额外 ARIA 修补;同时 <section></section> 自动成为可跳转 landmark,用户按 Ctrl+Alt+R 就能直达目标区块。
-
<section></section>必须配aria-labelledby指向内部<h2></h2>的 ID,不能只靠 class 或 textContent -
<h2></h2>必须在<section></section>内部,且层级连续(页面有唯一<h1></h1>,分组用<h2></h2>,子分类才用<h3></h3>) -
<caption></caption>应写具体描述(如Hospitalization cost breakdown),而非泛泛的“费用明细”
<th scope="row"> 和 <code><th scope="col"> 必须显式声明
<p>即使表格结构简单,漏掉 <code>scope 也会让屏幕阅读器无法判断某列数据归属哪个维度。例如 <th>First 60 days</th> 若无 scope="row",AT 可能误判为列标题,导致后续单元格读作“Medicare pays, All but ,600”,完全丢失行语义。
真实场景中,错误常出现在动态渲染表格:后端返回扁平数组,前端循环生成 <tr> 时忘记给首列 <code><th> 加 <code>scope,或误用 scope="col" 在行标题上。
- 行标题(描述数据行内容)用
scope="row" - 列标题(描述数据列含义)用
scope="col" - 避免在
<th> 上同时设 <code>scope和headers——二者功能重叠且可能冲突 - 响应式表格若隐藏某些列,需同步移除对应
<th> 的 <code>scope,否则 AT 仍会尝试播报已不可见的上下文单列键值对别用
<table>,改用 <code><dl></dl>或语义化段落像“保单号: ABC123”“生效日期: 2025-01-01”这类线性键值对,强行套
<table>(哪怕只有一列)会误导 AT 认为这是二维数据,触发不必要的行列导航模式,增加认知负荷。 <p>正确做法是用 <code><dl></dl>:每个<dt></dt>是术语(键),<dd></dd>是描述(值),天然表达一对一关系;或者用带aria-label的<p></p>组合,语义更轻量。-
<dl></dl>中<dt></dt>和<dd></dd>必须成对出现,不能跳过<dd></dd>留空 - 若后端返回的是对象 { policyNo: "ABC123", effectiveDate: "2025-01-01" },直接映射为
<dl></dl>比转换成二维数组再塞进<table> 更直白可靠 <li>CSS 可通过 <code>dl { display: grid; grid-template-columns: max-content 1fr; }实现与表格相似的对齐效果,不牺牲语义
复杂点不在写法本身,而在**是否愿意把业务逻辑分组当作独立语义单元来建模**——不是“怎么让一张表看起来有分区”,而是“这些分区本来就是不同表格”。一旦接受这个前提,结构就自然清晰了。
-
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











