caption必须是table的首个且唯一子元素,否则屏幕阅读器无法识别、w3c验证失败、导出时标题丢失;正确结构为标题……。

caption 必须是 table 的第一个子元素
不是“可以放”,而是“必须放”——caption标签如果没紧贴<table>开头写,浏览器就当它不存在。常见错误包括塞进<code><thead>里、放在<code><tbody>后面、或者用<code><div>包着再丢进去。这些写法会导致:<code>screen reader完全读不到标题,W3C 验证器报错,打印或导出时标题消失。
正确结构只有一种:
| 月份 | 新增数 |
|---|---|
| 1月 | 1,203 |
-
caption必须直接作为<table>的**首个且唯一**子元素<li>一个<code><table>里不能出现两个<code><caption></caption>,第二个会被静默忽略 - 别用
<th colspan="n">假装是标题——它只是个表头单元格,没有语义权重<h3>caption-side 只能作用于 table 元素</h3> <p>想把标题移到表格下方?别给<code>caption本身加caption-side: bottom,这行不通。这个 CSS 属性必须写在table选择器上,否则无效。示例:
table { caption-side: bottom; } /* ✅ 正确 */ caption { text-align: center; } /* ❌ caption { caption-side: bottom } 是无效的 */- 支持值只有
top和bottom;left/right兼容性差,不要用 - IE8+ 仅支持
top(默认),bottom在 IE 中基本不生效 - 别用
margin或position: absolute硬拉位置——会破坏可访问性,屏幕阅读器可能跳过
别用 div 或 h 标签模拟 caption
外面套个
<h3>销售数据</h3>再跟<table>,看起来一样,但语义断裂。辅助技术不会把这两者关联起来,WCAG 2.1 直接判定为可访问性缺陷。<ul> <li>视觉样式可用 CSS 调整,但语义不可替代:只有<code><caption></caption>会被识别为“该表格的标题” - 支持值只有
- 多表并存时,
caption内容要具体,避免“数据表”“表格1”这类泛称 - 空表格也建议写
<caption>暂无数据</caption>——否则 NVDA + Firefox 组合可能直接跳过整个表格
fieldset + legend 不是 caption 的替代方案
legend标签不能直接用于<table>,它只对<code><fieldset></fieldset>有效。有人把<table>包进<code><fieldset></fieldset>再加<legend></legend>,这确实能通过无障碍测试,但引入了额外语义——它表示“一组表单控件”,而纯数据表格不需要这个含义。
- 仅当表格内含
<input>、<select></select>等可交互元素,且需要逻辑分组时,才考虑<fieldset><legend></legend></fieldset> - 普通展示型表格,
<caption></caption>是唯一合规选择 - 同时用
<caption></caption>和<legend></legend>反而造成语义冗余,AT 可能重复播报
实际项目里最容易被忽略的,是导出 Excel 或生成 PDF 时caption内容根本不会自动带过去——它只活在 HTML 渲染层。如果业务要求导出文件必须含标题,得在 JS 导出逻辑里手动注入,或者用data-caption属性做冗余存储。











