:nth-of-type


Le sélecteur :nth-of-type (“n-ième du type”) vous permet de sélectionner un ou plusieurs éléments en fonction de leur ordre dans la source et selon des critères que vous déterminez. La spécification W3C le range parmi les “pseudo-classes structurelles”, ce qui signifie qu'il est utilisé pour appliquer un style au contenu en fonction de ses relations avec les éléments parents et enfants.

Supposons que nous ayons une liste non ordonnée et que nous voulions une présentation zébrée c'est à dire une alternance de bandes sombres et claires pour améliorer la lisibilité :

//HTML
<ul>
  <li>First Item</li>
  <li>Second Item</li>
  <li>Third Item</li>
  <li>Fourth Item</li>
  <li>Fifth Item</li>
</ul>

Plutôt que d'ajouter des classes à chaque item de la liste (par exemple .pair et .impair) on peut utiliser :nth-of-type :

//CSS
li {
  background: slategrey;
}
/* sélectionne un item sur deux, en commençant par le deuxième */
li:nth-of-type(2n) {
  background: lightslategrey;
}

Comme vous le voyez, :nth-of-type prend un argument (c'est le n-ième du type, mais il faut bien préciser comment on détermine ce n). Cela peut être un simple chiffre, les mots-clés even (pair) ou odd (impair), ou bien une formule.

Si un chiffre est spécifié, seul un élément sera sélectionné, par exemple :nth-of-type(2) sélectionnerait le deuxième item dans notre liste ci-dessus.

Si c'est un mot-clé ou une formule, une itération permettra de sélectionner le ou les éléments correspondants. Par exemple, :nth-of-type(even) sélectionnerait les items 2 et 4. :nth-of-type(3n+1) séléctionnerait les items 1 et 4.

Au passage, on voit ici que :nth-of-type(even) est l'équivalent de :nth-of-type(2n) et :nth-of-type(odd) est l'équivalent de :nth-of-type(2n+1) - sachant que lorsque la valeur de l'argument est inférieure ou égale à zéro, il n'y a pas de sélection. Inférieure à zéro ? Oui, car on pourrait très bien utiliser une formule du type :nth-of-type(2n-1) et pour n=0 on aurait un argument égal à -1. Dans ce cas, aucun élément ne serait sélectionné.

Pour illustrer tout ceci, voici quelques exemples de sélecteurs :nth-of-type :

See the Pen CSS-Tricks: :nth-of-type by Zachary Kain (@zakkain) on CodePen.

À noter

  • :nth-of-type procède par itération en commençant par le début de la liste. C'est la seule différence avec :nth-last-of-type qui commence par la fin de la liste.
  • le sélecteur :nth-of-type est très proche de :nth-child mais avec une différence essentielle : il est plus spécifique. Dans notre premier exemple, il donnerait le même résultat parce que nous ne faisons d'itérations que sur les éléments li, mais si nous avions un groupe plus complexe, :nth-child essaierait de cibler tous les éléments frères (siblings) et non pas les éléments frères limités au même type. C'est un point important à retenir concernant la puissance de :nth-child : il sélectionne tous les éléments frères et non pas seulement ceux qui sont spécifiés avant les deux-points :. Vous pouvez consulter l'article :nth-child pour plus de détails sur la différence entre les deux.

Allons plus loin sur la différence entre les deux

Prenons le HTML suivant :

//HTML
<section>
   <p>Petit</p>
   <p>Cochon</p>    <!-- Celui que je veux -->
</section>

Les deux CSS qui suivent parviendraient au même résultat :

//CSS
p:nth-child(2) { color: red; }

p:nth-of-type(2) { color: red; }

Et pourtant il y a une différence. En bon français, le sélecteur :nth-child nous dit de sélectionner un élément si :

  1. c'est un élément paragraphe
  2. c'est le second enfant d'un parent (quel qu'il soit)

Le sélecteur :nth-of-type, lui, dit ceci :

  1. sélectionner le second paragraphe enfant d'un parent (quel qu'il soit)

:nth-of-type est… comment dire… moins conditionnel.

Admettons que notre balisage soit maintenant :

//HTML
<section>
   <h1>Mots</h1>
   <p>Petit</p>
   <p>Cochon</p>    <!-- Celui que je veux -->
</section>

Ce CSS ne fonctionne plus :

//CSS
p:nth-child(2) { color: red; }

Celui-ci fonctionne encore :

//CSS
p:nth-of-type(2) { color: red; }

Quand je dis qu'il ne fonctionne plus, je veux dire que le sélecteur :nth-child sélectionne maintenant Petit au lieu de Cochon, parce que cet élément répond à la fois à la condition (1) être le deuxième enfant (de <section>) et (2) être un élément paragraphe.

Et quand je dis que le deuxième fonctionne encore, je veux dire que c'est bien Cochon qui est sélectionné, parce que c'est le deuxième paragraphe à l'intérieur de cet élément parent <section>.

Si nous ajoutions un <h2> après le <h1>, le sélecteur :nth-child ne sélectionnerait plus rien du tout parce que maintenant le deuxième enfant n'est plus un paragraphe. Le sélecteur :nth-of-type quant à lui fonctionnerait toujours.

Mon sentiment est que le sélecteur :nth-of-type est moins fragile et plus utile en règle générale, même si :nth-child est plus courant apparemment. Vous vous dites sans doute parfois “je veux sélectionner le second enfant d'un parent si c'est un paragraphe”, mais il y a des chances que vous vouliez plutôt “sélectionner le deuxième paragraphe” ou “sélectionner une ligne sur trois dans le tableau”, et ce sont là des cas où :nth-of-type (à mon avis) est un meilleur choix.

Dernière chose : je me suis rendu compte que la plupart de mes moments de “mais pourquoi ce #@/$!!! de :nth-child ne marche pas ??” venaient du fait que j'avais qualifié le sélecteur avec la balise. Donc lorsque j'utilise :nth-child je préfère en général spécifier le parent et ne pas qualifier :nth-child :

//CSS
dl :nth-child(2) {  } /* est préférable à */
dd:nth-child(2) {  } /* ceci */

Mais bien sûr, tout dépend de la situation exacte.

Quelques recettes

Il existe quelques "testeurs" de :nth-of-type que vous pouvez vous amuser à utiliser :

CSS-Tricks nth-child tester
Le testeur de Lea Verou
Nth-Test de Paul Maloney


Autres ressources à consulter sur ce sujet :

Autres articles intéressants :

dans La Cascade :

Quantity queries pour CSS, de Heydon Pickering

articles en anglais :

nthmaster, quelques exemples complexes d'utilisation des pseudo-classes structurelles :nth
W3schools.com avec possibilité de tester par vous-même


Cet article est pour l'essentiel tiré de l'almanach de CSS-Tricks de Chris Coyier, avec son aimable autorisation.

Sur l'auteur : est designer, blogger, conférencier. Créateur de CSS-Tricks, de CodePen, animateur du Podcast Shop Talk, il est l'auteur avec Jeff Starr de "Digging into WordPress". Vous pouvez le retrouver sur Twitter, Google+.

NdT : CSS-Tricks est un site ressource d'une richesse exceptionnelle, axé sur CSS et le web design en général. Vous pouvez suivre son actualité sur Twitter, Facebook, YouTube, GitHub. Mélange d'articles, de vidéos, de forums, de ressources diverses (jetez un coup d'oeil à son "Almanac" ), il est très populaire sur le web anglophone.

CodePen est un site où vous pouvez tester votre code, faire des maquettes, proposer vos dernières créations et recueillir les observations de vos pairs. C'est aussi une source d'inspiration pour vos propres designs.