В чем разница между 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)
с другой стороны:
-
Поскольку "тип" в :nth-of-type()
является тем же понятием, что и "тип" в селекторе типов, это семейство псевдоклассов предназначено для использования в сочетании с селекторами типов (хотя они все еще работают независимо). Вот почему p:nth-of-type(2)
можно выразить как лаконично, как "Выбрать второй p
элемент среди своих братьев и сестер". Это просто работает!
-
Однако, в отличие от :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>
Что выбрали, что нет, и почему?
-
Выбранные как p:nth-child(2)
и p:nth-of-type(2)
Первые два дочерних элемента этого элемента представляют собой оба элемента p
, позволяя этому элементу одновременно сопоставлять псевдоклассы для одного и того же целочисленного аргумента X, поскольку все эти независимые условия верны:
- это второй ребенок его родителя;
- это
p
элемент; а также - это второй элемент
p
внутри родителя.
-
Выбрано p:nth-child(2)
только
Этот второй ребенок является p
элементом, поэтому он соответствует p:nth-child(2)
.
Но это первый элемент p
(первый - header
), поэтому он не соответствует p:nth-of-type(2)
.
-
Выбрано p:nth-of-type(2)
только
Этот p
элемент является вторым элементом p
после первого, но он является третьим дочерним элементом, позволяющим ему соответствовать p:nth-of-type(2)
но не p:nth-child(2)
. Помните еще раз, что родительский элемент может иметь только один дочерний элемент :nth-child(X)
для определенного X за раз - предыдущий p
уже занимает слот :nth-child(2)
в контексте этот конкретный родительский элемент.
-
Не выбран
Этот p
элемент является единственным в своем родителе, и он не является его вторым потомком. Поэтому он не соответствует ни :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
, один 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>