16

p:nth-child(2)和 和有什么不一样p:nth-of-type(2)

根据W3Schools CSS 选择器参考

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

区别似乎是它的 parent 的child 和它的 parent<p> 元素

如果我们已经<p>在这两种情况下都提到了元素类型,并且关键字parent建立了父子关系,那么有什么区别呢?

4

8 回答 8

15

因为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/

于 2018-09-25T10:23:45.097 回答
10

这个问题可能会让你想起:first-child 和 :first-of-type 有什么区别?——事实上,两者之间有很多相似之处。这个问题与另一个问题有很大不同的地方是任意整数参数 X,如:nth-child(X):nth-of-type(X)。它们在原则上与“第一个”和“最后一个”对应项相似,但可能匹配的元素根据页面中的实际内容而有很大差异。

但首先,一些理论。请记住,简单的选择器是独立的条件。即使组合成复合选择器,它们也保持独立。这意味着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-childand :last-child(and, 同样, p:first-childand p:last-child)。

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

  1. 因为“类型”中:nth-of-type()的“类型”与类型选择器中的“类型”概念相同,所以这个伪类系列被设计为与类型选择器一起使用(即使它们仍然独立运行)。这就是为什么p:nth-of-type(2)可以简洁地表达为“p在其兄弟元素中选择第二个元素”。它只是工作!

  2. 但是,与:first-of-typeand不同:last-of-type的是,X 要求在其父元素中实际上存在许多相同类型的子元素。例如,如果p它的父元素中只有一个元素,p:nth-of-type(2)则不会匹配该父元素中的任何内容,即使该p元素保证匹配p:first-of-typeand p:last-of-type(以及,通过扩展,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>

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

  1. 被两者选择p:nth-child(2)p:nth-of-type(2)
    该元素的前两个子元素都是两个p元素,允许该元素同时匹配同一个整数参数 X 的两个伪类,因为所有这些独立条件都为真:

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

    但它是第一个p元素(第一个孩子是 a header),所以它不匹配p:nth-of-type(2)

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

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

  5. 选择者.parent > :nth-of-type(2)
    此元素是其父元素中的第二个类型。像:first-of-typeand一样:last-of-type,省略类型选择器允许伪类可能匹配同一个父级中的多个元素。与它们不同,实际匹配的数量取决于实际存在的每种元素类型的数量。

    这里有两个figure元素和三个p元素,允许:nth-of-type(2)匹配 afigure和 a p。但是只有 one header、 onehr和 one footer,因此它不会匹配任何这些类型的元素。

总之,:nth-child()and使用整数参数 X(即不是 An+B 的形式,系数 A 为 n),功能与/和/:nth-of-type()非常相似,主要区别在于参数以及页面本身,影响可以匹配多少不同的元素。:first-child:last-child:first-of-type:last-of-type:nth-of-type()

当然,不仅仅是一个简单的整数参数,还有很多其他的东西:nth-child():nth-of-type()但不用说它的细节和可能性超出了这个问题的范围。

于 2018-10-03T02:07:38.467 回答
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>

于 2018-09-27T11:12:17.403 回答
6

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

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

:nth-of-type(an+b)伪类表示法表示一个元素,该元素在文档树 ref 中具有一个+b-1 个同级元素,在它之前具有相同扩展元素名称

由此我们可以添加两个选择器之间的另一个重要区别,即nth-of-type通常与标签选择器一起使用nth-child而不需要标签选择器的事实。换句话说,nth-of-type可以选择多个元素nth-child只能选择一个元素。添加一个标签选择器nth-of-type会将选择限制为一个元素,添加一个标签选择器nth-child只会给我们定位的一个元素添加更多限制。1


第n个孩子()

此选择器将选择.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>

如果我们没有改变ph1将被选中,因为第二个孩子不是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>

第 n 个类型()

此选择器将选择 2ndp和 2nd h1nth-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>


如果您的容器仅包含一种类型的元素,则两个选择器肯定会给出相同的结果,但行为不同(即后面的 alogirthm 将不同)。您可能还会注意到,如果从两者中删除标签选择器,您也会得到相同的结果:

.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 中的整数进行选择。

于 2018-09-28T10:07:58.533 回答
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,但实际上标签是 a <span>

2) #content *:nth-child(2)-- apples to<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)只需要同一个标签节点列表中的第二个。

于 2018-09-25T08:53:43.297 回答
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>

于 2018-09-29T17:47:24.827 回答
1

正如MDN所说:

: nth-child() CSS 伪类根据元素在一组兄弟元素中的位置匹配元素。


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

但是,p:nth-of-type(2)将捕获<p>作为其父元素的第二个元素的元素,而不管元素的 index。这意味着一个元素可以有 100 个子元素,如果最后一个子元素是其兄弟元素中的第二个段落元素,它将受到列出的样式的影响。

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

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

总是正确的


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

当元素的前 2 个子元素属于同一类型时,这是正确的。


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

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


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

总是错误的,因为它类型的第 3 个元素不能是其父元素的第 2 个子元素。


例子:

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>

于 2018-10-04T00:46:38.383 回答
-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>
于 2018-10-02T16:37:25.263 回答