p:nth-​​child(2)和p:nth-​​of-type(2)有什么区别?

时间:2018-09-25 07:51:02

标签: css css3 css-selectors

p:nth-child(2)p:nth-of-type(2)有什么区别?

根据W3Schools CSS Selector Reference

  • p:nth-child(2):选择每个<p>元素作为其父元素的第二个子元素。
  • p:nth-of-type(2):选择每个<p>元素,它是其父元素的第二个<p>元素。

区别似乎是其父级的子级和其父级的<p> 元素

如果在两种情况下我们都已经将元素类型提到为<p>,并且关键字 parent 建立了 parent-child 关系,那么可以不同吗?

8 个答案:

答案 0 :(得分:13)

对于p:nth-child(2),如果它是一个段落,它将选择其父元素的第二个元素,而p:nth-of-type(2)将选择其父元素的第二个段落。如果您仍然感到困惑,让我们为您澄清一下。考虑下面的代码片段:

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

在这里,p:nth-child(2)将选择<p>Little</p>,因为它是其父级的第二个子级,并且是一个段落元素。

但是,p:nth-of-type(2)将选择<p>Piggy</p>,因为它将在其父级的所有段落中选择第二个段落。

帮助: https://css-tricks.com/the-difference-between-nth-child-and-nth-of-type/

答案 1 :(得分:9)

  • p:nth-​​child(1):表示它是任何父对象的第一个孩子,并且是段落类型。
  • p:nth-​​of-type(1):表示该类型段落在任何父级中的首次出现

p:nth-child(2){background:#f00;}
p:nth-of-type(2){background:#0f0;}
<div>
   <div>first child</div>
   <p>second child and first element of class "p"</p>
   <p>third child and second element of class "p"</p>
   <p>fourth child and third element of class "p"</p>
</div>

答案 2 :(得分:9)

这个问题可能使您想起What is the difference between :first-child and :first-of-type? -实际上,在两者之间有很多相似之处 。这个问题与另一个问题大不相同的地方是任意整数参数X,例如:nth-child(X):nth-of-type(X)。它们在原理上与对应的“第一个”和“最后一个”相似,但可能会根据页面中的实际情况极大地进行匹配。

但是首先,一些理论。请记住,simple selectors are independent conditions。即使结合到复合选择器中,它们也保持独立。这意味着p既不受:nth-child():nth-of-type()匹配方式的影响,也不受其影响。以这种方式组合它们仅意味着元素必须同时匹配其所有条件才能匹配。

在这里事情变得有趣。这种独立的匹配意味着我可以很简单地用简单的英语表达复合(和复杂)选择器,而无需改变选择器的含义。实际上,我现在可以通过某种方式使:nth-child(2):nth-of-type(2)之间的区别显得如此重要,以至于伪类之间可能完全不相关(“兄弟姐妹”部分)

  • p:nth-child(2):当且仅当它是一个p元素时,才选择第二个孩子。

  • p:nth-of-type(2):在同级中选择第二个p元素。

突然之间,它们听起来真的很不一样!这就是一些解释会有所帮助的地方。

任何元素一次只能有一个与:nth-child(X)匹配的整数X的单个子元素。这就是为什么我选择首先提到“第二个孩子”来强调它的原因。另外,此子元素仅在碰巧属于p:nth-child(X)类型时才与p匹配(请记住,“类型”是指标记名)。这与:first-child:last-child(以及类似的p:first-childp:last-child)非常一致。

另一方面,:nth-of-type(X)有两个方面:

  1. 由于:nth-of-type()中的“类型”与类型选择器中的“类型”是相同的概念,因此该伪类族被设计为与类型选择器结合使用(即使它们仍然独立运行)。这就是p:nth-of-type(2)可以简洁地表示为“在同级中选择第二个p元素的原因”。就是这样!

  2. 但是,与:first-of-type:last-of-type不同,X要求在其父元素中实际上存在许多相同类型的子元素。例如,如果父元素中只有一个p元素,即使保证p:nth-of-type(2)元素与p和{{ 1}}(以及扩展名p:first-of-type)。

说明:

p:last-of-type

选择了什么,没有选择什么,为什么?

  1. 同时由p:only-of-type<div class="parent"> <p>Paragraph</p> <p>Paragraph</p> <!-- [1] p:nth-child(2), p:nth-of-type(2) --> <p>Paragraph</p> <footer>Footer</footer> </div> <div class="parent"> <header>Header</header> <p>Paragraph</p> <!-- [2] p:nth-child(2) --> <p>Paragraph</p> <!-- [3] p:nth-of-type(2) --> <footer>Footer</footer> </div> <div class="parent"> <header>Header</header> <figure>Figure 1</figure> <p>Paragraph</p> <!-- [4] --> <footer>Footer</footer> </div> <div class="parent"> <header>Header</header> <p>Paragraph</p> <!-- [2] p:nth-child(2) --> <figure>Figure 1</figure> <hr> <figure>Figure 2</figure> <!-- [5] .parent > :nth-of-type(2) --> <p>Paragraph</p> <!-- [5] .parent > :nth-of-type(2) --> <p>Paragraph</p> <footer>Footer</footer> </div> 选择
    该元素的前两个子元素均为p:nth-child(2)元素,因为所有这些独立条件都为true,因此允许该元素为相同的整数参数X同时匹配两个伪类。

    • 这是其父母的第二个孩子;
    • 它是一个p:nth-of-type(2)元素;和
    • 它是其父元素中的第二个p元素。
  2. 仅由p选择
    第二个子元素是p元素,因此它与p:nth-child(2)匹配。

    但这是第一个p元素(第一个子元素是p:nth-child(2)),因此它与p不匹配。

  3. 仅由header选择
    p:nth-of-type(2)元素是上述元素之后的第二个p:nth-of-type(2)元素,但它是第三个子元素,允许它匹配p但不能匹配p。再次记住,父元素一次只能有一个子元素与p:nth-of-type(2)匹配特定的X —在以下情况下,前一个p:nth-child(2)已占用:nth-child(X)位置这个特定的父元素。

  4. 未选中
    p元素是其父元素中唯一的元素,而不是其第二个子元素。因此,它既不与:nth-child(2)也不与p匹配(即使没有通过类型选择器限定也不匹配;请参见下文)。

  5. :nth-child(2)选择
    此元素是其父元素中其类型的第二个元素。像:nth-of-type(2).parent > :nth-of-type(2)一样,省略类型选择器可以使伪类潜在地匹配同一父级中的多个元素。与它们不同,多少实际匹配取决于每个元素类型实际有多少。

    在这里,有两个:first-of-type元素和三个:last-of-type元素,从而允许figure匹配p:nth-of-type(2)。但是只有一个figure,一个p和一个header,因此它不会与任何这些类型的元素匹配。

总而言之,hrfooter具有整数参数X(即系数A为n的非An + B形式),其功能与:nth-child() /非常相似:nth-of-type():first-child / :last-child,主要区别在于参数和页面本身会影响与:first-of-type匹配的元素数量。

当然,:last-of-type:nth-of-type()除了简单的整数参数之外,还有很多其他功能,但是不用说,其详细信息和可能性不在此问题范围之内。

答案 3 :(得分:6)

其他答案凸显了两个选择器之间的主要区别,即nth-child将考虑同一容器内的所有元素(兄弟元素),而nth-of-type将考虑考虑在同一容器内具有相同类型的所有元素

  

:nth-child(an+b)伪类表示法表示一个元素   在文档树中之前有+ b-1个兄弟姐妹 ref

     

:nth-of-type(an+b)伪类符号表示一个元素,该元素在文档树之前具有+ b-1个兄弟姐妹,并且具有相同的扩展元素名称 ref

由此,我们可以在两个选择器之间添加另一个重要差异,即nth-of-type通常与标签选择器一起使用,而nth-child不需要标签选择器。换句话说,nth-of-type可以选择多个元素,而nth-child可以选择仅一个元素。用nth-of-type添加标签选择器会将选择范围限制为一个元素,而将标签选择器添加到nth-child则只会对我们定位的一个元素增加更多限制。 > 1


nth-child()

此选择器将选择.container的第二个孩子。

.container :nth-child(2) {
  border:1px solid red;
}
<div class="container">
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
  <p>aaa</p>
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
</div>

与上面的选择器相同,但是我们添加了标签限制:找到.container的第二个子元素,如果它是p的标签,则选择它。

.container p:nth-child(2) {
  border:1px solid red;
}
<div class="container">
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
  <p>aaa</p>
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
</div>

如果我们将p更改为h1,则不会选择任何内容,因为第二个孩子不是h1

.container h1:nth-child(2) {
  border:1px solid red;
}
<div class="container">
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
  <p>aaa</p>
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
</div>

nth-of-type()

此选择器将选择第二个p和第二个h1。将元素按相同类型分组后,nth-of-type的行为将类似于nth-child

.container :nth-of-type(2) {
  border:1px solid red;
}
<div class="container">
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
  <p>aaa</p>
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
</div>

所以我们在其中选择第二个孩子:

<div class="container">
  <p>aaa</p>
  <p>aaa</p> <-- this one -->
  <p>aaa</p>
  <p>aaa</p>
  <p>aaa</p>
</div>

然后在其中的第二个孩子:

<div class="container">
  <h1>title</h1>
  <h1>title</h1> <-- this one -->
</div>

添加标签选择器只会将选择范围限制为仅一组元素:

.container p:nth-of-type(2) {
  border:1px solid red;
}
.container h1:nth-of-type(2) {
  border:1px solid green;
}
<div class="container">
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
  <p>aaa</p>
  <p>aaa</p>
  <p>aaa</p>
  <h1>title</h1>
</div>


如果您的容器仅包含一种类型元素,则两个选择器将确定给出相同的结果,但不会表现相同(即,后面的算法不同) 。 您可能还会注意到,如果从两个标签选择器中都删除了标签选择器,则结果也将相同:

.container :nth-of-type(2) {
  border:1px solid red;
}
.container :nth-child(2) {
  color:red;
}

/* The below will also select the same
  .container p:nth-child(2)
  .container p:nth-of-type(2)
  .container *:nth-child(2)
  .container *:nth-of-type(2)
*/
<div class="container">
  <p>aaa</p>
  <p>aaa</p>
  <p>aaa</p>
  <p>aaa</p>
  <p>aaa</p>
</div>

另一个差异(这是个人想法)可能是两者的表现。 nth-child可以更快,因为它可以一次考虑所有同级元素,因此好像我们将有一个循环来检查所有元素。 nth-of-type需要同时考虑不同类型的元素,因此我们可能会进行更多处理,因此速度会变慢(这是我根据两者的工作原理得出的结论。我没有对此的正式证明)


1:我正在考虑在一个容器内使用nth-child / nth-of-type中的整数进行选择。

答案 4 :(得分:5)

假设我们有以下HTML:

<div id="content">
    <p>a1</p>
    <span>a2</span>
    <p>a3</p>
    <span>a4</span>
</div>

1)#content p:nth-child(2)-适用于0个元素
    因为p:nth-child(2)要求它是第二个孩子,并且标签是p,但实际上标签是<span>

2)#content *:nth-child(2)-苹果到<span>a2</span>
    因为*:nth-child(2)仅要求它是第二个孩子,而不需要标签名称。 *可以是任何标签名称。

3)#content p:nth-of-type(2)。 -适用于<p>a3</p>
    因为p:nth-of-type(2)表示<p>节点列表中的第二个。

4)#content *:nth-of-type(2)。 -适用于<p>a3</p><span>a4</span>
    因为*:nth-of-type(2)只需要同一个标记节点列表中的第二个。

答案 5 :(得分:2)

p:nth-child选择器在“普通英语”中表示在以下情况下选择元素:

  • 这是一个段落元素
  • 它是父母的第二个孩子(如果父母的第二个孩子不是<p> css,则不会生效)

p:nth-of-type选择器在“普通英语”中表示:

  • 选择第二段<p>的父级孩子(关心<p>,只需列出所有孩子<p>并接受)

.first p:nth-child(2) {
  background: blue // this css not effect
}

.first p:nth-of-type(2) {
  background: red
}
<div class="first">
  <p>This is 1st paragraph</p>
  <div>This is a div</div>
  <p>This is 2nd paragraph</p>
</div>

答案 6 :(得分:1)

MDN说:

  

:nth-​​child() CSS伪类根据元素在一组同级中的位置来匹配元素。


这意味着p:nth-child(2)仅捕获<p>个元素,它们是其父元素的第二个子元素。

但是,p:nth-of-type(2)将捕获<p>个元素,这些元素是其父元素的第二个元素,无论元素的索引如何。这意味着一个元素可以有100个子元素,如果最后一个子元素是其同级元素中的第二个段落元素,则该元素将受到所列样式的影响。

要记住的一些事情(尚未说过):

  

一个元素是nth-child(1)nth-of-type(1)

总是如此


  

一个元素是nth-child(2)nth-of-type(2)

当元素的前两个子元素具有相同类型时,这是正确的。


  

一个元素是nth-child(3)nth-of-type(2)

当元素的第一个和第三个子元素具有相同类型,而第二个子元素不是相同类型时,这是正确的。


  

一个元素是nth-child(2)nth-of-type(3)

这是总是错误的,因为属于其类型3的元素不能是其父级的第二个孩子。


示例:

p:nth-child(2)   { color: red; }
p:nth-of-type(2) { background-color: yellow; }
<div>
  <p>Paragraph 1</p> <!-- p:nth-child(1), p:nth-of-type(1) -->
  <p>Paragraph 2</p> <!-- p:nth-child(2), p:nth-of-type(2) -->
  <span></span>
</div>

<hr />

<div>
  <p>Paragraph 1</p> <!-- p:nth-child(1), p:nth-of-type(1) -->
  <span></span>
  <p>Paragraph 2</p> <!-- p:nth-child(3), p:nth-of-type(2) -->
</div>

答案 7 :(得分:-1)

p:nth-child(2):这将选择所有<p>元素,它们是其父元素内的第二个元素。第一个元素可以是任何其他元素。例如

<div>
    <h1>Title</h1>
    <p>Paragraph</p> ** p:nth-child(2)
    <p>Paragraph</p>
</div>

<div>
    <p>Paragraph</p>
    <p>Paragraph</p> ** p:nth-child(2)
    <p>Paragraph</p>
</div>

<div>
    <p>Paragraph</p>
    <h1>Text</h1>
    <p>Paragraph</p> ** None are selected
</div>

p:nth-of-type(2):这将选择所有<p>元素,它们是其父元素中第二次出现的<p>元素。

<div>
    <h1>Title</h1>
    <p>Paragraph</p>
    <p>Paragraph</p> ** p:nth-of-type(2)
</div>

<div>
    <h1>Title</h1>
    <h2>Subtitle</h2>
    <p>Paragraph</p>
    <h2>Subtitle</h2>
    <h2>Subtitle</h2>
    <h2>Subtitle</h2>
    <p>Paragraph</p> ** p:nth-of-type(2)
</div>

<div>
    <h1>Title</h1>
    <p>Paragraph</p> ** None are selected
</div>