La Cascade

Rechercher

La différence entre :nth-child et :nth-of-type

par Chris Coyier, 24 juillet 2022, css, pseudo-classes, article original paru le 12 novembre 2021 dans CSS-Tricks

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 :

  1. c'est un élément paragraphe
  2. 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 :

  1. 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

Voir la liste des articles de Chris Coyier traduits dans La Cascade.
Article original paru le 12 novembre 2021 dans CSS-Tricks
Traduit avec l'aimable autorisation de CSS-Tricks et de Chris Coyier.
Copyright CSS-Tricks © 2021