caption 必须作为 table 的第一个子元素且唯一,thead 必须用 tr 包裹表头单元格;二者语义不可混淆:caption 描述整表用途,thead 定义列含义,共同保障可访问性与结构化语义。

caption 元素必须直接放在 <table> 内部最前面
<p>很多人把 <code><caption></caption> 放在 <thead> 里,或者用 <code><div> 模拟标题,结果语义丢失、屏幕阅读器无法识别。正确写法是它作为 <code><table> 的第一个子元素,且只能有一个:
<pre class="brush:php;toolbar:false;"></pre>
<table>
<caption>2026年Q2销售汇总(单位:万元)</caption>
<thead><tr>
<th>区域</th>
<th>销售额</th>
</tr></thead>
<tbody><tr>
<td>华东</td>
<td>128.5</td>
</tr></tbody>
</table>
<p>注意:<code><caption></caption> 不是视觉装饰,它影响可访问性(AT 工具会读出“表格:……”)、打印样式(默认居顶显示),且 CSS 中可用 caption-side 控制上下位置(top 或 bottom)。
thead 必须包裹完整的行(<tr>),不能只包 <code><th>
<p>常见错误是把 <code><thead> 当成“表头单元格容器”,直接往里塞 <code><th>,导致 HTML 结构非法、渲染异常或被浏览器自动修正(可能破坏预期布局):
<p>❌ 错误写法:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher"><img
src="https://img.php.cn/upload/skill/000/000/081/179109368394970.jpg" alt="Wechat HTML Publisher" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="overflowclass">Wechat HTML Publisher</a>
<p class="overflowclass">直接上传HTML富文本到微信公众号草稿箱。支持完整的HTML格式,无需Markdown转换。</p>
</div>
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<pre class="brush:php;toolbar:false;"><thead>
<th>姓名</th>
<th>邮箱</th>
</thead></pre>
<p>✅ 正确写法(必须用 <code><tr> 包裹):
<pre class="brush:php;toolbar:false;"><thead><tr>
<th>姓名</th>
<th>邮箱</th>
</tr></thead></pre>
<p>多个表头行也一样,每行都得是独立的 <code><tr> —— 比如带分组标题的表头:
<pre class="brush:php;toolbar:false;"><thead>
<tr><th colspan="2">用户信息</th></tr>
<tr>
<th>姓名</th>
<th>邮箱</th>
</tr>
</thead></pre>
<h3>caption 和 thead 的语义分工不能混淆</h3>
<p><code><caption></caption> 描述整张表的用途或上下文(类似图表标题),而 <thead> 定义列维度含义(即“这一列代表什么”)。两者不可互相替代:
<ul>
<li>如果只想要“员工名单”这个标题,用 <code><caption></caption>
<tr>),不能只包 <code><th>
<p>常见错误是把 <code><thead> 当成“表头单元格容器”,直接往里塞 <code><th>,导致 HTML 结构非法、渲染异常或被浏览器自动修正(可能破坏预期布局):
<p>❌ 错误写法:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher"><img
src="https://img.php.cn/upload/skill/000/000/081/179109368394970.jpg" alt="Wechat HTML Publisher" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="overflowclass">Wechat HTML Publisher</a>
<p class="overflowclass">直接上传HTML富文本到微信公众号草稿箱。支持完整的HTML格式,无需Markdown转换。</p>
</div>
<a rel="nofollow" href="/xiazai/skill6712" title="Wechat HTML Publisher" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<pre class="brush:php;toolbar:false;"><thead>
<th>姓名</th>
<th>邮箱</th>
</thead></pre>
<p>✅ 正确写法(必须用 <code><tr> 包裹):
<pre class="brush:php;toolbar:false;"><thead><tr>
<th>姓名</th>
<th>邮箱</th>
</tr></thead></pre>
<p>多个表头行也一样,每行都得是独立的 <code><tr> —— 比如带分组标题的表头:
<pre class="brush:php;toolbar:false;"><thead>
<tr><th colspan="2">用户信息</th></tr>
<tr>
<th>姓名</th>
<th>邮箱</th>
</tr>
</thead></pre>
<h3>caption 和 thead 的语义分工不能混淆</h3>
<p><code><caption></caption> 描述整张表的用途或上下文(类似图表标题),而 <thead> 定义列维度含义(即“这一列代表什么”)。两者不可互相替代:
<ul>
<li>如果只想要“员工名单”这个标题,用 <code><caption></caption>
<thead> + <code><tr> + <code><th> 的职责
<li>把列名写进 <code><caption></caption> 会导致表格失去结构化语义,影响排序、导出、自动化解析另外,<caption></caption> 默认居中显示,但若需左对齐,CSS 应设 text-align: left 而非靠 <div> 嵌套——后者会破坏其语义层级。
<h3>兼容性和可访问性容易被忽略的细节</h3>
<p>部分旧版屏幕阅读器(如 JAWS 早期版本)对嵌套 <code><caption></caption> 或含交互内容(如按钮、链接)的 <caption></caption> 支持不佳;<thead> 若缺失,某些辅助技术可能无法正确关联数据单元格与列头(影响 <code><td> 的 <code>headers 属性解析)。
建议检查点:
- 用浏览器开发者工具查看
<table> 的 DOM 结构,确认 <code><caption></caption>是第一个子节点 - 用 Chrome 的 Lighthouse 运行「无障碍」审计,检查 “
<table> has a caption” 是否通过 <li>避免在 <code><caption></caption>中使用<img>或复杂内联样式,保持纯文本描述优先
真正难的不是写出来,而是让 <caption></caption> 和 <thead> 同时满足语义正确、视觉可控、机器可读这三个条件——多数人卡在第二个和第三个之间反复妥协。</thead>










