В чем разница между p: nth-child (2) и p: nth-of-type (2)?

В чем разница между 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 устанавливает отношение родитель-потомок, то в чем же разница?

Ответ 1

Этот вопрос может напомнить вам о том, в чем разница между: 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-child и :last-child (и, аналогично, p:first-child и p: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 гарантированно соответствует p:first-of-type и 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 (первый - 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-type и :last-of-type, оставляя вне селектор типов, позволяет псевдоклассу потенциально сопоставлять более одного элемента внутри одного и того же родителя. В отличие от них, сколько их фактически соответствует, зависит от того, сколько на самом деле каждого типа элемента.

    Здесь есть два figure элемента и три элемента p, позволяющие :nth-of-type(2) соответствовать figure и p. Но есть только один header, один hr и один footer, поэтому он не будет соответствовать элементам любого из этих типов.

В заключение :nth-child() и :nth-of-type(), с целым аргументом X (т.е. Не в форме An + B с коэффициентом A из n), функционируют аналогично :first-child/:last-child и :first-of-type/:last-of-type, причем основное отличие заключается в том, что аргумент, а также сама страница влияет на количество различных элементов, которые могут быть сопоставлены с :nth-of-type().

Конечно, есть еще много чего :nth-child() и :nth-of-type() чем просто простой целочисленный аргумент, но, разумеется, детали и возможности этого не выходят за рамки этого вопроса.

Ответ 2

Для 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/

Ответ 3

  • 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>

Ответ 4

Другие ответы подчеркивают основное различие между обоими селекторами, что является тем фактом, что nth-child рассмотрит все элементы внутри одного и того же контейнера (элементы siblings) и nth-of-type рассмотрит все элементы одного типа внутри одного и того же контейнера,

:nth-child(an+b) псевдокласса представляет собой элемент, который имеет + b-1 братьев и сестер перед ним в дереве документов ref

:nth-of-type(an+b) псевдо-класс обозначение представляет собой элемент, который имеет + B-1 брат и сестра с тем же расширенным именем элемента перед ним в документе дерево иого

Из этого мы можем добавить еще одно важное различие между двумя селекторами, что является фактом, что nth-of-type обычно используется с селектором тегов, тогда как nth-child не нуждается в селекторе тегов. Другими словами, nth-of-type может выбрать несколько элементов, но nth-child может выбрать только один элемент. Добавление селектора тэгов с nth-of-type ограничит выбор одним элементом и добавление селектора тэгов в nth-child просто добавит больше ограничений на один элемент, на который мы нацеливаемся. 1


п-й ребенок()

Этот селектор выберет второй ребенок .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>

Ответ 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) требует только второго в том же списке узлов тегов.

Ответ 6

p:nth-child селектор 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>

Ответ 7

Как говорит MDN:

Псевдокласс класса nth-child() сопоставляет элементы, основанные на их позиции в группе братьев и сестер.


Это означает, что 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)

Это верно, когда элемент сначала 2 ребенка одного типа.


элемент представляет собой nth-child(3) и nth-of-type(2)

Это верно, когда элемент 1-го и 3-го детей одного типа, но второй ребенок - нет.


элемент представляет собой nth-child(2) и nth-of-type(3)

Это всегда false, поскольку элемент, который является третьим по своему типу, не может быть вторым потомком родителя.


Пример:

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>

Ответ 8

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>