Um elemento pai pode ter um ou mais elementos filho:
<div class="parent">
<div>Child</div>
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Entre essas crianças, apenas uma delas pode ser a primeira. Isso é correspondido por :first-child
:
<div class="parent">
<div>Child</div> <!-- :first-child -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
A diferença entre :first-child
e :first-of-type
é que :first-of-type
corresponderá ao primeiro elemento de seu tipo de elemento, que em HTML é representado por seu nome de tag, mesmo se esse elemento não for o primeiro filho do pai . Até agora, os elementos filhos que estamos vendo foram todos div
s, mas tenha paciência comigo, vou chegar lá em breve.
Por enquanto, o inverso também é verdadeiro: qualquer :first-child
um também é :first-of-type
por necessidade. Como o primeiro filho aqui também é o primeiro div
, ele corresponderá a ambas as pseudo classes, bem como ao seletor de tipo div
:
<div class="parent">
<div>Child</div> <!-- div:first-child, div:first-of-type -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Agora, se você mudar o tipo do primeiro filho div
para outra coisa, como h1
, ainda será o primeiro filho, mas não será mais o primeiro div
obviamente; em vez disso, ele se torna o primeiro (e único) h1
. Se houver quaisquer outros div
elementos seguindo este primeiro filho dentro do mesmo pai, o primeiro desses div
elementos corresponderá div:first-of-type
. No exemplo dado, o segundo filho se torna o primeiro div
depois que o primeiro filho é alterado para um 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>
Observe que :first-child
é equivalente a :nth-child(1)
.
Isso também implica que, embora qualquer elemento possa ter apenas um único elemento filho correspondente :first-child
por vez, ele pode e terá tantos filhos correspondendo à :first-of-type
pseudo classe quanto o número de tipos de filhos que ela possui. Em nosso exemplo, o seletor .parent > :first-of-type
(com uma *
qualificação implícita de :first-of-type
pseudo) corresponderá a dois elementos, não apenas a um:
<div class="parent">
<h1>Child</h1> <!-- .parent > :first-of-type -->
<div>Child</div> <!-- .parent > :first-of-type -->
<div>Child</div>
<div>Child</div>
</div>
O mesmo é verdadeiro para :last-child
e :last-of-type
: qualquer :last-child
é por necessidade também :last-of-type
, visto que absolutamente nenhum outro elemento o segue dentro de seu pai. Porém, como o último div
é também o último filho, h1
não pode ser o último filho, apesar de ser o último de seu tipo.
:nth-child()
e :nth-of-type()
funcionam de maneira muito semelhante em princípio quando usados com um argumento inteiro arbitrário (como no :nth-child(1)
exemplo mencionado acima), mas onde eles diferem é no número potencial de elementos correspondidos por :nth-of-type()
. Isso é abordado em detalhes em Qual é a diferença entre p: n-ésimo filho (2) e p: n-ésimo-do-tipo (2)?