Родительский элемент может иметь один или несколько дочерних элементов:
<div class="parent">
<div>Child</div>
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Среди этих детей только один может быть первым. Этому соответствует :first-child
:
<div class="parent">
<div>Child</div> <!-- :first-child -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Разница между :first-child
и :first-of-type
заключается в том, что :first-of-type
он соответствует первому элементу своего типа элемента, который в HTML представлен его именем тега, даже если этот элемент не является первым дочерним элементом родительского элемента . Пока что все дочерние элементы, на которые мы смотрим, были div
, но потерпите меня, я вернусь к этому чуть позже.
А пока верно и обратное: любое :first-child
- тоже :first-of-type
по необходимости. Поскольку первый дочерний элемент здесь также является первым div
, он будет соответствовать обоим псевдоклассам, а также селектору типа div
:
<div class="parent">
<div>Child</div> <!-- div:first-child, div:first-of-type -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Теперь, если вы измените тип первого дочернего элемента с div
на что-то другое, например h1
, он все равно будет первым дочерним элементом , но, div
очевидно , он больше не будет первым ; вместо этого он становится первым (и единственным) h1
. Если div
после этого первого дочернего элемента в пределах того же родителя есть какие-либо другие div
элементы, тогда будет совпадать первый из этих элементов div:first-of-type
. В данном примере второй дочерний элемент становится первым div
после того, как первый дочерний элемент изменен на h1
:
<div class="parent">
<h1>Child</h1> <!-- h1:first-child, h1:first-of-type -->
<div>Child</div> <!-- div:nth-child(2), div:first-of-type -->
<div>Child</div>
<div>Child</div>
</div>
Обратите внимание, что :first-child
это эквивалентно :nth-child(1)
.
Это также означает, что, хотя у любого элемента может быть только один соответствующий дочерний элемент :first-child
за раз, он может и будет иметь столько дочерних элементов, соответствующих :first-of-type
псевдоклассу, сколько типов дочерних элементов у него есть. В нашем примере селектор .parent > :first-of-type
(с неявной *
квалификацией :first-of-type
псевдо) будет соответствовать двум элементам, а не только одному:
<div class="parent">
<h1>Child</h1> <!-- .parent > :first-of-type -->
<div>Child</div> <!-- .parent > :first-of-type -->
<div>Child</div>
<div>Child</div>
</div>
То же самое верно и для :last-child
and :last-of-type
: any также :last-child
является обязательным :last-of-type
, поскольку за ним не следует ни один другой элемент в пределах своего родителя. Тем не менее, поскольку последний div
также является последним ребенком, он h1
не может быть последним ребенком, несмотря на то, что он последний в своем типе.
:nth-child()
и :nth-of-type()
работают очень похоже в принципе при использовании с произвольным целочисленным аргументом (как в :nth-child(1)
примере, упомянутом выше), но где они различаются, так это в потенциальном количестве элементов, которым соответствуют :nth-of-type()
. Это подробно описано в разделе В чем разница между p: nth-child (2) и p: nth-of-type (2)?