:nth-child(odd)匹配父元素下第奇数个同类型子元素,但受所有子元素序号影响;:nth-of-type(odd)则仅按同标签元素计数,更适应含干扰节点的结构。

nth-child(n) 的基本写法和常见误区
:nth-child(odd) 和 :nth-child(even) 是最直接的奇偶行选择方式,但要注意:它匹配的是父元素下第 n 个子元素,且必须是同类型标签(比如都是 <li> 或都是 <tr>),不是“第 n 个同类元素”。如果父容器里混有其他标签(如 <code><div>、<code><p></p>),序号会跳过它们继续计数,但匹配仍要求标签名一致。
常见错误现象:ul li:nth-child(odd) 没生效,实际是因为 <ul></ul> 下第一个子元素是注释、空格文本节点,或前面插了 <div class="header"> —— 此时 <code><li> 已不是第 1、3、5 个子元素,nth-child 就选不中。
使用场景建议:
- 纯结构干净的列表(如手写
<ul><li>...</li></ul>)可用:nth-child(odd) - 表格中推荐用
tbody tr:nth-child(odd),并确保<tbody> 显式存在(避免浏览器自动补全导致意外嵌套)<h3>替代方案:nth-of-type 更稳妥</h3> <p>当父容器内存在干扰子元素(如标题、分隔线、广告位 <code><div>)时,<code>:nth-of-type()更可靠——它只按同标签名的顺序计数,忽略其他类型节点。立即学习“前端免费学习笔记(深入)”;
例如:
<ul> <li>第一项</li> <div class="ad">广告</div> <li>第二项</li> <li>第三项</li> </ul>
li:nth-child(odd)只能选中第一个<li>(它是第 1 个子元素),第三个<li>是第 4 个子元素 → 偶数 → 不匹配。
而li:nth-of-type(odd)会把所有<li>单独编号:第 1、2、3 个<li>→ 选中第 1 和第 3 个,真正实现“奇数项”。注意点:
-
:nth-of-type不能跨标签类型匹配,tr:nth-of-type(odd)对<thead> 和 <code><tbody> 分开计数<li>如果表格用了 <code><thead><tr>...</tr></thead>,tbody tr:nth-of-type(odd)才能正确作用于数据行 - 不要写
:nth-child(0)(无效,CSS 规范中 n 从 1 开始) -
:nth-child(2n+1)等价于:nth-child(odd),但可读性差,调试时容易看错系数 - 若需从第 2 行开始交替(比如跳过表头),用
tr:nth-child(n+2):nth-child(odd),而不是试图改起始偏移量
性能与兼容性:现代项目优先用 :nth-child
:nth-child在所有主流浏览器(Chrome 4+、Firefox 3.5+、Safari 3.1+、Edge 12+)中支持良好,IE9+ 也支持。性能上和:nth-of-type几乎无差别,现代渲染引擎已优化这类伪类计算。但要注意两个边界情况:
表格中真正实用的写法
表格交替背景最常踩的坑是:样式被
<thead> 或 <code><caption></caption>干扰,或单元格<td> 自身设置了背景盖过了行背景。<p>推荐组合:</p> <ul><li>显式写出 <code><tbody>,避免浏览器解析歧义<li>给 <code>tbody tr设置背景,而非td -
- 用
tbody tr:nth-child(even)配浅灰,tbody tr:nth-child(odd)配白底,对比清晰
table tbody tr:nth-child(odd) {
background-color: #fff;
}
table tbody tr:nth-child(even) {
background-color: #f8f9fa;
}
如果表格有悬停效果,记得把 :hover 放在 :nth-child 后面,否则会被覆盖:
tbody tr:hover 要写在 tbody tr:nth-child(even) 之后才生效。
真正容易被忽略的是:当表格行通过 JS 动态插入或删除时,:nth-child 会实时重算,但如果你用 class 控制(如 .row-odd),就必须手动维护 class —— 这反而更麻烦。所以原生伪类仍是首选,只要 HTML 结构可控。


















