用tr:nth-child(odd)和tr:nth-child(even)最直接纯CSS实现隔行变色,但需限定tbody tr以避免thead干扰;其按DOM物理位置计数,非视觉行序,混入其他节点会导致错位,此时应改用nth-of-type。

用 tr:nth-child(even) 和 tr:nth-child(odd) 最直接
纯 CSS 就能搞定,不需要 JS 或重复写 class。浏览器原生支持,现代项目里这是首选方案。
-
tr:nth-child(even)匹配第 2、4、6… 行(注意:是 DOM 中的顺序位置,不是渲染后可见行) -
tr:nth-child(odd)匹配第 1、3、5… 行 - 如果表格有
thead或tfoot,tr计数仍从整个table根节点开始算 —— 比如thead里有 1 行,那第一个tbody tr就是第 2 个tr,会被当成even - 想让
tbody内部独立计数,改用tbody tr:nth-child(even)
table tr:nth-child(even) { background-color: #f5f5f5; }
table tr:nth-child(odd) { background-color: #ffffff; }
遇到 或带 rowspan 的行怎么办
nth-child 不受单元格合并影响,但视觉上可能错位 —— 因为 rowspan 会让某一行“占多行高度”,而交替色仍按行标签数量机械切换。
- 如果只是偶发几处
rowspan,手动给对应tr加 class(如class="highlight")更可控 -
本身不干扰tr选择器,但若用它设了背景色,会和tr背景色叠加,优先级取决于 CSS 权重和声明顺序 - 避免在同一个
tr上同时用background-color和设背景,容易出现色块断裂
IE8 及更老浏览器不支持 nth-child 怎么办
IE8 只支持 :first-child,不支持 nth-child。如果必须兼容,得退回到 JS 或服务端生成 class。
- 最轻量的 JS 方案:
document.querySelectorAll('table tbody tr').forEach((tr, i) => { tr.classList.toggle('even', i % 2 === 0); }); - 服务端渲染时,在循环中判断索引奇偶,输出
或 - 别用 IE 条件注释 + 额外样式表 —— 维护成本高,且现代构建工具通常已放弃 IE8 支持
为什么有时第一行没变色或颜色颠倒
大概率是 CSS 选择器权重或作用范围出问题,而不是逻辑错误。
- 检查是否写了
table tr却忘了加空格,写成tabletr(这会匹配标签) - 确认没有更高优先级的内联样式(
style="background: …")覆盖了 CSS 规则 - 如果用了 CSS-in-JS 或 Shadow DOM,
tr:nth-child()可能因作用域隔离失效,需显式穿透或改用tr:nth-of-type() -
nth-of-type()按标签类型计数,比nth-child()更抗干扰(比如忽略thead tr),但语义稍弱
CSS 交替色看着简单,真正上线前最好在真实数据(含空行、合并单元格、动态插入行)下跑一遍,否则上线后才发现第 7 行突然白底变灰底,排查起来反而比加 JS 还慢。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











