:nth-child(An+B) 按元素在父容器中的实际子节点序号(n≥0整数)代入公式计算匹配位置,只认位置不认标签类型;若中间存在其他兄弟节点(如文本、注释、不同标签),会导致序号偏移,此时应改用 :nth-of-type()。

什么是 :nth-child(An+B) 的实际匹配逻辑?
它不是“选第 A 行、第 2A 行……”,而是按「元素在其父容器中的位置序号」套入公式 An+B(n 为 ≥0 的整数)计算出所有合法位置,再选取对应序号的子元素。比如 :nth-child(2n+1) 会匹配位置 1、3、5……(即奇数位),但前提是这些位置上**确实存在该类型元素**——它不关心元素标签名或类名,只认位置。
常见误解:以为 :nth-child(3n) 能选中“每行第三个 div”,结果发现隔了几行才生效。原因往往是中间夹了其他兄弟元素(如 p、文本节点、注释),导致目标 div 实际位置序号根本不是 3、6、9……
怎么确保 :nth-child() 选中的是你想要的元素?
先用浏览器开发者工具检查目标元素的「实际子元素序号」:右键 → 「检查」→ 看它在父节点下的 child index(或手动数 DOM 树中同级节点)。如果目标是第 4 个子节点,就别硬套 3n;如果想选“每个块级元素中的第 2 个 span”,:nth-child() 大概率不行——该用 :nth-of-type()。
-
:nth-child(2n)→ 偶数位置(2, 4, 6…),不是“偶数行” -
:nth-child(3n+2)→ 位置 2, 5, 8, 11…(注意起始是 +2,不是 +1) -
:nth-child(-n+3)→ 仅前 3 个子元素(n=0→3,n=1→2,n=2→1,n=3→0,停止) - 负系数如
-2n+5有效,但 n 仍从 0 开始代入,结果 ≤0 即终止
:nth-child() 和 :nth-of-type() 到底该用哪个?
如果你的目标元素在父容器中**不连续出现**,或者中间混有其他标签(比如表格里 tr 之间插了 caption,或列表里 li 前有 h3),:nth-child() 就会错位。这时应改用 :nth-of-type()——它只统计同类型标签的位置。
立即学习“前端免费学习笔记(深入)”;
例如父元素内结构是:<h2>标题</h2><p>文字</p><p>第二段</p><div>内容</div>,想给第二个 p 加样式:p:nth-child(3) 会失败(因为 p 是第 2、3 个子元素,但第 3 个子元素是 p,没错——等等,这里要小心:第 2 个子元素才是第一个 p,第 3 个是第二个 p,所以 p:nth-child(3) 实际能命中;但如果中间加个 span,序号就全乱了)。更稳的方式是 p:nth-of-type(2),它直接找第二个 p,无视中间有什么。
常见错误现象和调试建议
写完样式没生效?大概率是公式算出来的位置上压根没有你要的元素,或被其他 CSS 优先级覆盖。打开 DevTools 的 Styles 面板,看目标元素是否被该选择器列出——没列出,说明没匹配上;列出了但样式无效,点开旁边的删除线查优先级。
- 误写成
:nth-child(n+0):等价于所有子元素,但不如直接写*或省略 - 用
n当变量名幻想可赋值:n是数学占位符,不能设为具体数字 - 忽略 HTML 空格/换行生成的文本节点:它们也算子节点!
display: none的元素仍参与计数 - 在 Flex/Grid 容器中误以为“视觉顺序”影响
:nth-child():不,它永远按 DOM 顺序,跟布局无关
真正麻烦的从来不是公式本身,而是你默认的“第几行”和 DOM 树里的“第几个子节点”对不上——动手前,先数清楚。


















