:nth-child和:nth-of-type行为不同:前者按子元素位置匹配,后者按同类型元素顺序匹配;:first-child与:first-of-type同理,一字之差可能导致完全不匹配。

:nth-child 和 :first-child 不是“有哪些”的罗列对象,而是**有明确行为差异、必须按场景选对的两个关键伪类**。用错一个,样式就失效——尤其在混合子元素(比如 div 里夹着 p、h2、span)时。
为什么 :nth-child(n) 经常“选不到”你想要的元素?
它只认「位置」,不认「类型」::nth-child(2) 意思是“父元素下的第二个子元素”,然后才判断这个子元素是不是你写的标签名。如果第二个子元素是 h2,而你写的是 p:nth-child(2),那这条规则完全不生效。
- 常见错误现象:给
ul写了li:nth-child(2),但第二项没变色——检查一下ul开头有没有注释、空格、或意外插入的div - 适用场景:父元素下所有子元素类型一致(如纯
li列表),且你关心的是视觉顺序位置 - 参数本质:
n从 0 开始代入公式,2n+1等价于odd,3n表示第 3、6、9…个位置(不是第 3、第 6 个li)
:nth-of-type(n) 才是你真正需要“找第 n 个 li”的解法
它先筛出所有同类型元素(比如全部 p),再按它们在父元素中出现的顺序编号,:nth-of-type(2) 就是“第二个 p”,不管它前面隔着几个 h3 或 div。
- 典型使用场景:文章正文里混排标题、段落、图片,你想让“第三个段落”加粗,就得用
p:nth-of-type(3) - 和
:nth-child权重相同(都是 10),但逻辑完全不同;切勿当成同义词互换 - 兼容性无顾虑:IE9+ 全支持,现代项目可放心用
:first-child vs :first-of-type:一字之差,结果可能全空
假设父容器是:
标题
第一段
立即学习“前端免费学习笔记(深入)”;
第二段
-
p:first-child→ 不匹配任何元素(因为第一个子元素是h2) -
p:first-of-type→ 匹配“第一段”(它是第一个p) -
h2:first-child→ 成功匹配(h2正好是第一个子元素) - 同理,
:last-child和:last-of-type行为对称,但含义不可互换
隔行变色这种“刚需”,到底该用哪个?
绝大多数情况下,用 :nth-child(even) 最稳妥——前提是你的列表结构干净(如纯 tr 或纯 li)。但如果表格里插了 thead、tfoot 或额外 tr class="divider",就会错位。
- 纯
tbody > tr结构 →tbody > tr:nth-child(even) - 含
thead的表格 → 改用tbody > tr:nth-of-type(even)(只数tbody下的tr) - 想跳过首行标题 →
tr:nth-child(n+2)(从第 2 个子元素开始选),不是tr:nth-child(2n)
:nth-child 和 :nth-of-type 都只看直接子元素层级**。如果你写了 ul li:nth-child(1),它不会去 ul 的孙子辈里找,也不会跨过嵌套的 ol 去算。结构一复杂,就必须靠开发者自己判断:我要控制的是“第几个孩子”,还是“第几个同类元素”。










