La différence entre :nth-child et :nth-of-type
La différence entre nth-child et nth-of-type n'est pas forcément évidente et pourtant elle est fondamentale.
Supposons que nous ayons ce HTML :
<section>
<p>Little</p>
<p>Piggy</p>
<!-- nous voulons celui-ci -->
</section>
Les deux CSS qui suivent feront exactement la même chose :
p:nth-child(2) {
color: red;
}
p:nth-of-type(2) {
color: red;
}
Pourtant, il y aura une différence évidemment.
La définition de notre sélecteur :nth-child
, en bon français, signifie sélectionne un élément si :
- c'est un élément paragraphe
- c'est le deuxième enfant de son élément parent
La définition de notre sélecteur :nth-of-type
, en bon français, signifie :
- sélectionne le deuxième paragraphe enfant de son élément parent
:nth-of-type
est donc, comment dire... moins conditionnel.
Supposons que notre balisage soit maintenant :
<section>
<h1>Words</h1>
<p>Little</p>
<p>Piggy</p>
<!-- nous voulons celui-ci -->
</section>
Ceci ne fonctionne plus :
p:nth-child(2) {
color: red;
} /* incorrect */
Ceci fonctionne :
p:nth-of-type(2) {
color: red;
} /* fonctionne */
Par "incorrect", je veux dire que le sélecteur :nth-child
sélectionne maintenant le mot "Little" au lieu de "Piggy" parce que cet élément est à la fois 1) le second enfant et 2) un élément paragraphe. Par "fonctionne", je veux dire que "Piggy" est toujours sélectionné parce qu'il est le deuxième paragraphe dans cet élément parent.
Si j'ajoutais un titre <h2>
après le titre principal <h1>
, le sélecteur :nth-child
ne sélectionnerait rien du tout puisque maintenant le deuxième enfant n'est plus un paragraphe, et donc le sélecteur ne trouve rien.
Le :nth-of-type
, lui, fonctionne comme attendu.
Mon sentiment est que :nth-of-type
est moins fragile et plus utile en général, même si :nth-child
est plus souvent utilisé (semble-t-il). Combien de fois vous êtes-vous demandé "je veux sélectionner le deuxième enfant d'un élément parent s'il se trouve être un paragraphe" ? Parfois, peut-être, mais il est plus probable que vous vouliez "sélectionner le deuxième paragraphe" ou "sélectionner chaque troisième rangée d'un tableau", qui sont des cas où :nth-of-type
est un choix plus solide (là encore, de mon point de vue).
J'ai l'impresson que mes moments de "Grrrr... mais pourquoi ce sélecteur :nth-child
ne marche pas ?!" viennent du fait que j'ai qualifié le sélecteur avec un tag et que le numéro d'ordre de l'enfant ne correspond pas à ce tag. Par conséquent, lorsque j'utilise :nth-child
, je me rends compte qu'il est préférable de spécifier le parent et de laisser :nth-child
non qualifié.
dl :nth-child(2) {
} /* est mieux que */
dd:nth-child(2) {
} /* ceci */
Mais bien sûr tout dépend de la situation exacte.
Vous pouvez jouer avec ce super outil de test ! Voir également la page MDN de :last-of-type et la page MDN de :nth-child