On a vu précédemment ( Principes généraux -> La cascade) comment le navigateur retenait une déclaration de style parmi 3 origines possible.
Il peut arriver que l'étape de la cascade ne soit pas suffisante car dans la même origine plusieurs déclarations vont entrer en conflit ou en concurrence.
On peut par exemple styler différemment les liens :
a {
color: black;
text-decoration: underline;
}
#menu a {
color: red;
text-decoration: none;
display: block;
}
Ici, de façon naturelle on déduit que les liens dans le menu auront une mise en forme différente des liens dans le reste de la page parce que le sélecteur utilisé pour la règle de style est plus précis, plus spécifique.
Mais comment faire quand le choix n'est pas aussi évident que le précédent :
#menu li a:hover {
color: red;
}
ul li a:hover {
color: blue;
}
Suivant la spécificité des sélecteurs, le navigateur va calculer le poids d'une déclaration de la façon suivante.
Les déclarations de style qui se trouve dans le code HTML sous la forme d'un
attribut style pésent le plus lourd. On a ensuite par
poids décroissant : les sélecteurs d'identifiant, les sélecteurs de
classe/attributs/pseudo-classe et les sélecteurs d'élément/pseudo-éléments
(ex. :before et :after).
Le poids totale est obtenu par la concaténation des poids des différents sélecteurs de la règle et la déclaration avec le poids le plus élevé l'emporte.
Quelques exemples :
| Sélecteurs | A | I | C | E | Poids |
<h2 style="color: red;"> |
1 | 0 | 0 | 0 | 1,0,0,0 |
#menu { border: 1px solid; } |
0 | 1 | 0 | 0 | 0,1,0,0 |
.grand { font-size: 40px; } |
0 | 0 | 1 | 0 | 0,0,1,0 |
ul { margin: 20px; } |
0 | 0 | 0 | 1 | 0,0,0,1 |
ul li { color: red } |
0 | 0 | 0 | 2 | 0,0,0,2 |
#menu ul { margin: 10px; } |
0 | 1 | 0 | 1 | 0,1,0,1 |
ul.grand { font-size: 30px; } |
0 | 0 | 1 | 1 | 0,0,1,1 |
#menu ul li a:hover { color: red; } |
0 | 1 | 1 | 3 | 0,1,1,3 |
input[type="text"] {display: block;} |
0 | 0 | 1 | 1 | 0,0,1,1 |
Si à l'issue de ce calcul, des déclarations ont un poids égale, c'est la dernière déclaration dans le code CSS qui est utilisée.
Il existe un moyen pour passer outre cette règle de définition de la
spécificité des sélecteurs. Si la déclaration se termine par le
mot-clé !important c'est elle qui sera prise en compte,
quelque soit par ailleurs le poids des sélecteurs de sa règle.
a {
color: blue !important; /* sera toujours utilisé */
}
#menu a {
color: red; /* ne sera pas retenu */
}
Cet exercice est une adaptation de CSS Diner (Made by @flukeout, with special thanks to @k88hudson, @antlam7 and @smashman2004.
Dans la zone de saisie clignotante en bleu, saisissez le bon
sélecteur pour passer chaque niveau.
En passant la souris au dessus des choses sur la table, le code HTML correspondant est mis en bleu.
De la même façon, en passant la souris au dessus du code HTML, les choses
correspondantes sur la table sont entourées en bleu.