Cascade CSS et spécificité

Tous les sélecteurs CSS ne sont pas égaux. Certains sélecteurs sont plus “puissants” que d’autres, et parviennent à surcharger des règles CSS plus faibles. Un sélecteur par identifiant – #titre – est plus “spécifique”, donc plus puissant, qu’un sélecteur par classe – .titre – qui est plus puissant qu’un sélecteur par élément – h1.

Voici comment la documentation du W3C explique le principe:

Régles de spécificité dans la documentation CSS du W3C

Quelques exemples:

* {
    color: red;
}

Une règle utilisant comme sélecteur l’astérisque s’appliquera à tous les éléments d’une page, et aura la spécificité la plus basse, càd de zéro.

li {
    color: red;
}

La même règle utilisant un sélecteur par élément. On aura une spécificité de (a=0 b=0 c=1), donc de 1.

ul li {
    color: red;
}

Si on utilise deux sélecteurs de même type, leur puissance s’additionne. Avec le code qui précède, on aura une valeur de (a=0 b=0 c=2), donc 0-0-2.

.red {
    color: red;
}

On utilise maintenant sélecteur de type “classe”. Un monte d’un niveau de puissance (a=0 b=1 c=0), ce qui se traduit par une spécificité de 0-1-0.

header .red {
    color: red;
}

Ici le résultat sera (a=0 b=1 c=1), autrement dit: 0-1-1.

#sidebar {
    color: red;
}

Avec l’utilisation d’un sélecteur ID (#), on monte au troisième niveau de puissance. La valeur de ce sélecteur sera (a=1 b=0 c=0), autrement dit: 1-0-0.

Les différences de puissance entre les sélecteurs font que l’ordre de la “cascade CSS” ne s’applique pas forcéement.

Par exemple dans ce code:

#header a { color: blue; }     /* a=1 b=0 c=1 -> specificity = 1-0-1 */
.header nav > a { color: red } /* a=0 b=1 c=2 -> specificity = 0-1-2 */

De manière non intuitive, c’est la ligne du haut (couleur bleue) qui “gagne”, car sa spécificité est plus puissante que celle du bas (1-0-1 vs. 0-1-2).

Un codepen de démonstration:

Explications visuelles

Pour mieux comprendre ce principe, des designers ont créés des explicatifs visuels:

Visualisation basée sur The Shining: http://cdn.w3cplus.com/sites/default/files/blogs/2013/1312/CSS_Specificity.jpg

Visualisation basée sur Star Wars, Specificity Wars, par Andy Clarke (créé en 2005, mis à jour en 2018).

Specificity Wars

Visualisation aquatique, CSS SpeciFISHity, par Estelle Weyl.

Bonnes pratiques

Selon l’experte en performance du code CSS Nicole Sullivan, il faut privilégier les classes et éviter les sélecteurs ID. Voici un exemple de code à éviter:

#sidebar #accounts #accountDetails h3{}

Classes are our friends. Seeing a lot of IDs is actually very bad. Run from this kind of code!

Ressources

Calculateurs de spécificité:

Explication en vidéo

Articles et tutoriels

Cascade CSS et priorité des sélecteurs, par Laurent Denis, 2005

La spécificité des sélecteurs, Grafikart, 2018