最常用写法是tr:nth-child(odd)和tr:nth-child(even),但需注意它按父容器中所有tr位置计数,thead/tfoot中的tr也参与计数,易导致隔行变色错位;应限定为tbody tr:nth-child(odd)以确保仅作用于数据行。
直接用 tr:nth-child(odd) 和 tr:nth-child(even) 是最常用的方式,但要注意:它匹配的是 所有 tr 元素在父容器中的位置顺序,不是“表格数据行”的逻辑序号。如果 thead 或 tfoot 里有 tr,它们

常见错误现象:表头 thead > tr 被算作第 1 行,导致第一行数据变成 nth-child(2),隔行色错位。
tbody tr:nth-child(odd)
tbody 标签(HTML 允许省略),浏览器会自动补上,但选择器仍需显式写 tbody 才可靠tr:nth-of-type() —— 它按标签名统计,但 tr 在 table 中通常只有一种类型,效果看似一样,实则语义错误且不可控: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
td, th 设 background-color: transparent,或直接对 td, th 应用 :nth-child()
border-collapse: collapse 时,相邻 cell 边框合并,但背景色仍各自渲染,不影响隔行tr:hover 设了背景色,会覆盖隔行色,需提高选择器优先级或重置 hoverodd 和 2n+1 等价,但后者可微调起始点。比如想从第 2 行开始隔行(即第 2、4、6… 行着色),用 tr:nth-child(2n) 即可。
真正容易被忽略的是:当表格动态增删行时,:nth-child() 会实时重算,无需 JS 干预;但如果你用 JS 手动加 class 控制样式,就必须同步更新 class,否则序号会错乱。