### Spécificité des sélecteurs

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.

spécificité et poids

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 */
    }

### Resto CSS

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.

Pratiquer l'exercice.