HervéRenault.fr

Logo de CSS3

Calculer la spécificité des sélecteurs CSS

Parfois, stylelint affiche des erreurs de spécificité pas faciles à saisir quand on n'a plus les yeux en face des trous 🥵 Par exemple
Expected selector "nav #foobar-container > a" to come before selector "#primary-nav .active > a"
Heureusement, il y a un outil pour ça, le Specificity Calculator.

Pour un calcul rapide sans avoir rien à installer, il y a la version en ligne.
Pour reprendre l'exemple, on clique sur le bouton "Sort by specifity" et on voit que
#primary-nav .active > a est affiché en haut, donc il est plus spécifique que nav #foobar-container > a
Normal : il a 1 id, 1 classe, 1 élément (ou pseudo-élément comme ::before), alors que l'autre a 1 id, 0 classe (ou pseudo-classe, ou attribut), 2 éléments. 111 > 102.

On peut aussi installer le module par npm install specificity et l'utiliser dans node en interactif :

$ node
Welcome to Node.js v20.15.1.
Type ".help" for more information.
> calc = await import("./node_modules/specificity/dist/esm/index.js");
[Module: null prototype] {
  calculate: [Function: calculate],
  calculateWithDetails: [Function: calculateWithDetails],
  compare: [Function: compare],
  compareDesc: [Function: compareDesc]
}
> calc.compare(calc.calculate('nav #foobar-container > a'), calc.calculate('#primary-nav .active > a'));
-1

Comme l'explique la doc, -1 signifie que le premier sélecteur est moins spécifique que le deuxième. Donc c'est bon, c'est dans le bon ordre.
Personnellement, j'aurais préféré que ce soit une valeur de 1 qui signifie que c'est le bon ordre, mais 🤷