最常用写法是tr:nth-child(odd)和tr:nth-child(even),但需注意它按父容器中所有tr位置计数,thead/tfoot中的tr也参与计数,易导致隔行变色错位;应限定为tbody tr:nth-child(odd)以确保仅作用于数据行。

table tr:nth-child(odd) 和 tr:nth-child(even) 的基本写法
直接用 tr:nth-child(odd) 和 tr:nth-child(even) 是最常用的方式,但要注意:它匹配的是 所有 tr 元素在父容器中的位置顺序,不是“表格数据行”的逻辑序号。如果 thead 或 tfoot 里有 tr,它们也会被计入计数。
常见错误现象:表头 thead > tr 被算作第 1 行,导致第一行数据变成 nth-child(2),隔行色错位。
- 只对 tbody 内的行生效:
tbody tr:nth-child(odd) - 若无
tbody标签(HTML 允许省略),浏览器会自动补上,但选择器仍需显式写tbody才可靠 - 避免用
tr:nth-of-type()—— 它按标签名统计,但tr在 table 中通常只有一种类型,效果看似一样,实则语义错误且不可控
兼容性与 fallback 方案
:nth-child() 在 IE9+ 支持良好,IE8 及更早版本不支持。如果必须兼容 IE8,不能依赖 CSS 伪类,得靠 JS 或服务端加 class。
纯 CSS fallback 几乎不可行;JS 方案极轻量:
立即学习“前端免费学习笔记(深入)”;
document.querySelectorAll('tbody tr').forEach((tr, i) => {
tr.classList.toggle('odd', i % 2 === 0);
});
然后定义 .odd { background-color: #f5f5f5; }。注意:这个 i 是 tbody 内索引,天然避开 thead 干扰。
background-color 不生效的几个典型原因
即使选择器写对了,颜色也可能没显示——多半是层叠或继承问题。
- tr 本身没有背景,但 td/th 有白色背景,会盖住 tr 的
background-color - 解决办法:给
td, th设background-color: transparent,或直接对td, th应用:nth-child() - table 设置了
border-collapse: collapse时,相邻 cell 边框合并,但背景色仍各自渲染,不影响隔行 - 某些 UI 框架(如 Bootstrap)给
tr:hover设了背景色,会覆盖隔行色,需提高选择器优先级或重置 hover
用 :nth-child(2n+1) 替代 odd 更灵活?
odd 和 2n+1 等价,但后者可微调起始点。比如想从第 2 行开始隔行(即第 2、4、6… 行着色),用 tr:nth-child(2n) 即可。
真正容易被忽略的是:当表格动态增删行时,:nth-child() 会实时重算,无需 JS 干预;但如果你用 JS 手动加 class 控制样式,就必须同步更新 class,否则序号会错乱。










