有网友留言问了个看着挺基础的问题:「在 CSS 中 table、th、tr、td 都分别有什么用?能举例说明一下吗?」
我第一眼看到的不是”这四个标签怎么答”,而是提问里藏着一个小误会。把这个误会先掰开,四个标签反而一遍就记住了。
table、tr、th、td 是 HTML 标签,既不是 CSS 属性,也不是 CSS 规则。CSS 只是拿它们的名字当选择器,选中之后给它们定样子。
打个比方:HTML 像盖房子时砌墙、隔房间,定死了哪间是卧室、哪间是厨房;CSS 像刷什么颜色的墙、铺什么地板、家具怎么摆。房间还是那几间,换套装修方案不会把厨房变成卧室。
所以一句话:HTML 管”这是什么”,CSS 管”它长什么样”。之所以容易混,是因为写样式时确实要在 CSS 里写 table { }、th, td { } 这类选择器——但被选中的对象,始终是 HTML 元素本身。
我顺手画了张图,把四层关系标出来:

图:table、tr、th、td 的四层嵌套关系,右侧为各标签职责
蓝色大框是整张表,四条浅蓝横条是四行,第一行的琥珀色格子是表头,其余白格子是数据格。对照着看下面这张表:
| 标签 | 全称 | 管什么 | 在哪一层 |
|---|---|---|---|
table |
Table | 整张表格的容器,表格里所有内容都得装在它里面 | 最外层 |
tr |
Table Row | 定义一行,是单元格的横向容器,自己不装文字 | table 里面 |
th |
Table Header | 表头单元格,语义上是列(或行)的标题;浏览器默认加粗、居中 | tr 里面 |
td |
Table Data | 数据单元格,表格里真正的内容都写在它里面 | tr 里面 |
嵌套关系是死的:table > tr > th | td。一个 tr 里可以全是 th(表头行)、全是 td(数据行),也可以混着来。文字不能直接写进 tr,必须再套一层 th 或 td——这是新手最常犯的错,写完发现内容跑到表格外面去了,多半就是它。
拿我自己熟悉的一张物态变化表当例子,HTML 是这样写的:
<table>
<tr>
<th>物态变化</th><th>吸热或放热</th><th>生活例子</th>
</tr>
<tr>
<td>熔化</td><td>吸热</td><td>冰化成水</td>
</tr>
<tr>
<td>凝固</td><td>放热</td><td>水结冰</td>
</tr>
<tr>
<td>汽化</td><td>吸热</td><td>水烧开</td>
</tr>
</table>
光有这段 HTML,浏览器里是连边框都没有的一堆文字。原因就是开头那句:HTML 只交代了结构,没交代外观。
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #999; padding: 8px; text-align: center; }
th { background: #FAEEDA; }
tr:nth-child(even) td { background: #F5F5F5; }
border-collapse: collapse:把相邻格子的两条边合并成一条线;th, td 这条:给每个格子画边框、撑开内边距、文字居中;th 单独一条:给表头换个底色,一眼分清哪行是标题;tr:nth-child(even):挑出偶数行做隔行变色,长表格读起来不串行。注意最后一条:tr 自己不画边框,但完全可以被 CSS 选中,拿来管整行的背景最合适。这也是”HTML 管结构、CSS 管外观”的一个具体例子。
th 不是”加粗版 td“。它是有语义的标签,屏幕阅读器靠它告诉使用者”这一格是列标题”。别为了省事全用 td 再手动加粗,该用 th 就用 th。border-collapse: collapse,边框会变成两条线。相邻单元格各画各的边,看起来又粗又脏,这是”表格怎么这么丑”最常见的原因。改主题时如果文章里的表格没边框、挤成一团,多半不是 HTML 写错了,而是 style.css 里压根没给 table、th、td 写边框和内边距规则。补上上面那四行基本就正常了。这个排查过程我另外写过一篇:表格小得像脚注:一次 WordPress 主题 CSS 的排查与修复,一篇讲标签结构,一篇讲主题样式,正好互补。
参考出处:MDN 中文《HTML 表格基础》、MDN《th 元素参考》。
table 圈住整张表,tr 切行,th 是标题格,td 是数据格;CSS 只负责它们长什么样。把这两件事分开记,表格这块基本就不会再绕了。