:nth-child(even)和:nth-child(odd)是标准写法,匹配DOM位置上的偶数/奇数子元素;:nth-child-even不存在,浏览器会忽略;在table中需注意tbody等包裹层导致计数上下文变化。

nth-child(even) 和 nth-child(odd) 才是标准写法
没有 nth-child-even 这个选择器,这是常见误解。CSS 规范中只有 :nth-child() 伪类,括号内填 even 或 odd 表示偶数位或奇数位元素(注意:是“位置”,不是“行号”)。
典型错误是直接写 nth-child-even,浏览器会完全忽略该规则,背景色不会生效。
-
:nth-child(even)匹配第 2、4、6… 个子元素(按 DOM 树顺序,从父容器第一个子元素开始计数) -
:nth-child(odd)匹配第 1、3、5… 个子元素 - 它不关心元素类型——哪怕中间夹着
<div>或注释,计数也不会跳过
表格中用 :nth-child(even) 可能失效的真相
在 <table> 中直接对 tr 写 tr:nth-child(even) 很容易出问题,因为 <thead>、<tbody>、<tfoot> 是包裹层,实际 tr 的父元素是这些 tbody 等,而不是 table 本身。
所以 tr:nth-child(even) 实际匹配的是每个 <tbody> 内部的第 2、4… 个 tr,而非整张表的第 2、4 行。
立即学习“前端免费学习笔记(深入)”;
- 正确做法:给
<tbody>加 class(如class="data-body"),再写.data-body tr:nth-child(even) - 更稳妥方案:用
:nth-of-type()(但仅当tr是其父元素下唯一一类标签时才可靠) - 若需跨 thead/tbody 统一编号,只能靠 JS 动态加 class,CSS 无解
替代方案::nth-of-type() 更贴近“视觉行”直觉
当父容器里混有其他标签(如 <div>、<p>),:nth-child() 的“位置计数”会偏移,而 :nth-of-type() 只统计同类型元素(比如只数所有 tr),有时更符合预期。
例如:
<tbody> <tr><td>A</td></tr> <div>note</div> <tr><td>B</td></tr> <tr><td>C</td></tr> </tbody>
-
tr:nth-child(even)→ 不匹配任何tr(因为第 2 个子元素是<div>) -
tr:nth-of-type(even)→ 匹配第 2 个tr(即 “C” 所在行) - 但注意:
:nth-of-type()不支持公式如2n+1,只能用odd/even或具体数字
兼容性与性能提醒
:nth-child() 在 IE9+ 完全支持,IE8 及以下不支持——如果还需兼容 IE8,必须用 JS 添加 class="even"/"odd"。
性能上,现代浏览器优化良好,但嵌套过深(如 div div div tr:nth-child(even))或配合复杂属性选择器时,仍可能触发重排/重绘。
- 避免写成
tbody tr:nth-child(even) td,应写为tbody tr:nth-child(even)并设置background-color到tr上(更高效) - 不要在动画关键帧里频繁切换
:nth-child相关样式,它不触发硬件加速 - 若表格数据量极大(>1000 行),CSS 隔行变色本身没问题,但滚动卡顿大概率来自其他因素(如未使用
will-change: transform或虚拟滚动缺失)


















