td:first-child和td:last-child仅在无colspan/rowspan且每行结构一致的纯数据表格中可靠;选视觉列应优先用td:nth-child(n)或data-col属性,避免伪类失效。

td:first-child 和 td:last-child 能直接用,但只在简单结构下可靠
这两个伪类最常用,写法简洁:td:first-child 选每行第一个 td,td:last-child 选每行最后一个 td。前提是表格没有 colspan 或 rowspan,且所有行结构一致。
常见错误现象:某行开头是 th、或中间有合并单元格,td:first-child 就会跳过那行——因为它只认“该行中第一个 td 元素”,而不是“视觉上第一列的所有单元格”。
- 适用场景:纯数据表格,每行都由相同数量的
td构成,无跨列/跨行 - 注意
th不会被td:first-child匹配,如需同时覆盖表头,得单独写th:first-child - 如果
<tbody> 外还有 <code><thead> 或 <code><tfoot>,<code>tr:last-child可能命中<tfoot> 里的行,而非数据末行 <h3>要选“视觉上第 N 列”,必须用 :nth-child(N),不能只靠 first/last</h3> <p>想稳稳选中第二列?写 <code>td:nth-child(2)。它按 DOM 中的物理位置计数,和标签类型无关,比:first-child更可控。但要注意:
tr:nth-child(3) td:nth-child(2)是选“第三行、第二列”的单个单元格;而td:nth-child(2)单独使用,才是选所有行中“物理位置为第 2 的td”——也就是视觉上的第二列。- 第一列 =
td:nth-child(1),最后一列 =td:nth-child(N)(N 为列总数),不是td:last-child - 列数不固定时(比如响应式隐藏某些列),
nth-child会失效,此时应改用 class 标记,例如td[data-col="price"] - IE8 不支持
:nth-child,如需兼容,只能靠 JS 补充 class 或服务端渲染标记
遇到 rowspan/colspan 就别硬扛,CSS 无解时得换思路
只要任意单元格用了
rowspan="2",td:nth-child(2)在下一行就会错位——因为 DOM 里那一列“空缺”了,后续单元格的物理序号全变了。这是 CSS 选择器的固有限制,不是写法问题。真实项目中,一旦表格含合并单元格,纯 CSS 无法可靠选出“视觉列”。浏览器根本不维护“列坐标映射”,只按 HTML 树顺序解析。
- 推荐做法:服务端或 JS 渲染时,给每列单元格加上统一
data-col属性,如<td data-col="1">、<code><td data-col="last"> <li>避免用 <code>colgroup+col配样式,它只控制宽度/背景等有限属性,无法设字体、边框等单元格级样式 - 若必须动态处理,可用 JS 遍历
table.rows,按cellIndex归类后加 class,再用 CSS 定义 - 必须设
table { border-collapse: separate } - 给
td:first-child加border-radius同时,还得在 table 外层容器加overflow: hidden,否则圆角会溢出 - 如果表格有
thead,首列圆角还涉及th:first-child,得一并处理,且注意th和td的 padding/line-height 是否一致,否则圆角对不齐
border-radius 对表格圆角无效?先关掉 border-collapse
有人试过给
td:first-child加border-top-left-radius,结果没反应——大概率是因为table { border-collapse: collapse }在起作用。这个声明会让浏览器把相邻边框“挤”在一起,直接吞掉圆角。想让首列左上角真出圆角,得拆开边框模型:
- 第一列 =
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











