Родительский элемент может иметь один или несколько дочерних элементов:
<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-childand :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)?