Un élément parent peut avoir un ou plusieurs éléments enfants:
<div class="parent">
<div>Child</div>
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Parmi ces enfants, un seul d'entre eux peut être le premier. Ceci correspond à :first-child
:
<div class="parent">
<div>Child</div> <!-- :first-child -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
La différence entre :first-child
et :first-of-type
est qu'il :first-of-type
correspondra au premier élément de son type d'élément, qui en HTML est représenté par son nom de balise, même si cet élément n'est pas le premier enfant du parent . Jusqu'à présent, les éléments enfants que nous examinons ont tous été des div
s, mais soyez indulgents, j'y reviendrai dans un instant.
Pour l'instant, l'inverse est également vrai: tout :first-child
est également :first-of-type
par nécessité. Puisque le premier enfant ici est également le premier div
, il correspondra aux deux pseudo-classes, ainsi qu'au sélecteur de type div
:
<div class="parent">
<div>Child</div> <!-- div:first-child, div:first-of-type -->
<div>Child</div>
<div>Child</div>
<div>Child</div>
</div>
Maintenant, si vous changez le type du premier enfant de div
à quelque chose d'autre, comme h1
, ce sera toujours le premier enfant, mais ce ne sera plus le premier div
évidemment; au lieu de cela, il devient le premier (et le seul) h1
. S'il y a d'autres div
éléments suivant ce premier enfant dans le même parent, le premier de ces div
éléments correspondra alors div:first-of-type
. Dans l'exemple donné, le deuxième enfant devient le premier div
après que le premier enfant est changé en 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>
Notez que cela :first-child
équivaut à :nth-child(1)
.
Cela implique également que bien qu'un élément ne puisse avoir qu'un seul élément enfant correspondant :first-child
à la fois, il peut et aura autant d'enfants correspondant à la :first-of-type
pseudo-classe que le nombre de types d'enfants qu'il possède. Dans notre exemple, le sélecteur .parent > :first-of-type
(avec une *
qualification implicite du :first-of-type
pseudo) correspondra à deux éléments, pas seulement un:
<div class="parent">
<h1>Child</h1> <!-- .parent > :first-of-type -->
<div>Child</div> <!-- .parent > :first-of-type -->
<div>Child</div>
<div>Child</div>
</div>
Il en va de même pour :last-child
and :last-of-type
: any l' :last-child
est aussi par nécessité :last-of-type
, puisque absolument aucun autre élément ne le suit dans son parent. Pourtant, comme le dernier div
est aussi le dernier enfant, le h1
ne peut pas être le dernier, bien qu'il soit le dernier de son type.
:nth-child()
et :nth-of-type()
fonctionnent de manière très similaire en principe lorsqu'ils sont utilisés avec un argument entier arbitraire (comme dans l' :nth-child(1)
exemple mentionné ci-dessus), mais là où ils diffèrent, c'est dans le nombre potentiel d'éléments correspondant à :nth-of-type()
. Ceci est traité en détail dans Quelle est la différence entre p: nth-child (2) et p: nth-of-type (2)?