: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),但逻辑完全不同;切勿当成同义词互换: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 去算。结构一复杂,就必须靠开发者自己判断:我要控制的是“第几个孩子”,还是“第几个同类元素”。