:nth-child 和 :nth-of-type 之间的区别

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您的旅程各个阶段提供云产品。 立即开始使用 $200 免费赠送额度!

假设我们有以下 HTML 代码

<section>
   <p>Little</p>
   <p>Piggy</p>    <!-- We want this one -->
</section>

它们将执行完全相同的事情

p:nth-child(2) { color: red; }
p:nth-of-type(2) { color: red; }

当然,它们之间还是有区别的。

上面的 :nth-child 选择器,用“白话文”来说,意味着如果满足以下条件,则选择一个元素:

  1. 它是段落元素
  2. 它是父元素的第二个子元素

上面的 :nth-of-type 选择器,用“白话文”来说,意味着

  1. 选择父元素的第二个段落子元素

:nth-of-type 是… 怎样才能说清楚呢… 条件较少

假设我们的标记更改为以下内容

<section>
   <h1>Words</h1>
   <p>Little</p>
   <p>Piggy</p>    <!-- We want this one -->
</section>

这会失效

p:nth-child(2) { color: red; } /* Now incorrect */

但这仍然有效

p:nth-of-type(2) { color: red; } /* Still works */

“失效”是指上面的 :nth-child 选择器现在选择单词“Little”,而不是“Piggy”,因为该元素满足这两个条件:1) 它是第二个子元素,2) 它是段落元素。 “仍然有效”是指“Piggy”仍然被选中,因为它是在该父元素下的第二个段落。

如果我们在 <h1> 之后添加一个 <h2> , :nth-child 选择器 将完全不会选择任何内容 ,因为现在第二个子元素不再是段落,因此该选择器找不到任何内容。 :nth-of-type 仍然有效。

我觉得 :nth-of-type 不太容易出错,而且一般情况下更有用,尽管 :nth-child 更为常见(在我看来)。 你觉得有多少次会想“我想选择父元素的第二个子元素,只要它恰好是一个段落”。 也许有时候会,但更有可能的是你想“选择第二个段落”或“选择每个第三个表格行”,在这些情况下 :nth-of-type 是(在我看来)更强大的选择。

我发现我大部分的“ 糟糕,为什么这个 :nth-child 选择器不起作用?!” 时刻都是因为我最终用标签限定了选择器,而该数字子元素实际上并不是那个标签。 因此,在使用 :nth-child 时,我发现通常最好是指定父元素,并将 :nth-child 保持为非标签限定的。

dl :nth-child(2) {  } /* is better than */
dd:nth-child(2) {  } /* this */

但是,当然,这完全取决于具体情况。

:nth-of-type 的浏览器支持相当不错… Firefox 3.5+、Opera 9.5+、Chrome 2+、Safari 3.1+、IE 9+。

我本来想说,如果你需要更深层的支持,jQuery 可以帮上忙(在那里使用选择器,应用一个类,然后用该类进行样式设置),但事实上 jQuery 放弃了对 :nth-of-type 的支持。 我觉得很奇怪。 我听说这是因为使用率低。 如果你想走这条路, 这里有一个插件可以帮你找回来 jQuery 1.9 现在再次支持 :nth-of-type (回到 IE 6),所以这也是一个选择。

相关内容:不要忘记很棒的兄弟姐妹 :first-of-type:last-of-type:nth-last-of-type:only-of-type 在此了解更多信息。

如果你想玩一个视觉示例, 查看这个工具!