:nth-child(n)按父元素所有子节点总序号计数,:nth-of-type(n)只对同标签元素单独编号;前者易因换行、注释等干扰失效,后者更稳定,且伪元素和自闭合标签不参与后者计数。

因为它们数的根本不是同一批东西。一个按父元素所有子节点总序号数,一个只数同标签的兄弟节点——中间夹个 <div>、换行、注释 <!-- -->,结果立刻分叉。
为什么 p:nth-child(2) 经常不生效
它要求两个条件同时成立:必须是父元素的第 2 个子节点,且该节点必须是 p 标签。只要第 2 个子节点是文本节点(比如缩进换行)、<div>、<script> 或注释,整个选择器就静默失败,连报错都没有。
- 服务端模板常自动插入
<!-- header -->,让原本第 1 个p变成第 2 个子节点 - Markdown 渲染器把空行转成空白文本节点,悄悄偏移序号
- 构建工具开发环境未压缩 HTML(保留换行),上线后压缩掉换行,行为不一致
:nth-of-type(2) 为什么看起来更“稳”
它执行的是两步独立操作:先收集所有 p 元素,再对它们单独编号。前面插了 5 个 <h3>、3 条注释、2 个空格?全都不影响——第 2 个 p 就是第 2 个 p。
-
div.foo:nth-of-type(2)中的.foo不参与计数,只作为附加筛选;真正计数的是所有div标签 - 伪元素(如
::before)、自闭合标签(<img>、<input>)不进入:nth-of-type的同类筛选池,但会参与:nth-child计数 -
<LI>和<li>在 HTML 中视为同一类型,XHTML 模式下才可能区分(极少遇到)
调试时怎么一眼分清该用哪个
别猜,直接验证:在 DevTools Styles 面板临时加一条 div:nth-child(3) { outline: 2px solid red; },看红框套在谁身上;再换成 div:nth-of-type(3),对比两次高亮对象是否一致。不一致?说明中间混了其他 div 或非 div 节点。
立即学习“前端免费学习笔记(深入)”;
- 更可靠的做法是右键父元素 → “Edit as HTML”,看清真实子节点顺序——不是折叠后的 Elements 视图,而是原始解析树
-
section p:nth-child(2)不会跨层找嵌套在article里的p;它只看section的直接子元素中,第 2 个是不是p -
:nth-child(0)无效(n必须 ≥ 1),odd/even关键字严格小写,IE8 完全不支持:nth-系列
最容易被忽略的底层细节:伪类匹配永远只发生在**直接父元素的子节点层**。结构越复杂,越要先看清 DOM 真实构成,而不是依赖视觉预期。


















