Un truc qui arrive parfois quand on s’attaque à du CSS c’est l’élément qui se retrouve ciblé par plusieurs instructions, évidemment contradictoires. Deux trucs qu’on apprend bien vite quand on fait du CSS pour ce genre de cas c’est :
- La dernière déclaration ciblant un élément gagne toujours (Ce qui est faux dans l’absolu, mais on a cette impression que c’est vrai)
- En ciblant au plus précis son élément, on évite les problèmes
- (On peut utiliser !important… Pourquoi entre parenthèse, car c’est une solution qui peut vite devenir impossible à maintenir…)
Dernièrement j’ai du travailler sur une surcharge css d’une interface. C’est à dire appliquer un rendu différent que le rendu de base mais simplement en ajoutant une nouvelle feuille de style et non pas en subsituant.
Ce faisant, j’ai rencontré un cas particulier qui m’a interpelé. Alors que je tenais pour acquis ma première assertion (« La dernière déclaration ciblant un élément gagne toujours ») je suis tombé sur un cas l’invalidant !
Soit ce HTML :
<div id="conteneurId" class="conteneur"> <div id="elementId" class="content">Elément</div> </div>
Avec cette CSS :
.conteneur #elementId{ background:red; } #elementId{ background:blue; }
Qu’est ce qui ressort ? Il ressort un fond rouge (red) !
En effet, le sélecteur est plus précis. Mais quelle logique exactement ? Car là le code est simple et on « voit » clairement que le premier sélecteur est plus précis donc a plus de poids. Qu’en est il avec des chaines de sélection css à rallonge ?
Et bien il y a un moyen facile de savoir. Un moyen logique de calculer le « poids » de la chaîne de sélection et donc quand elle va intervenir par rapport à d’autres.
- Calculer le nombre d’id (avec #) et multipliez par 100
- Calculer le nombre de class (avec .) et multipliez par 10
- Calculer le nombre de balises HTML et ce sont les unités
Additionner après les 3 chiffres et cela donne le poids de la chaîne.
Il suffit après de comparer les poids de chaque chaîne. La chaîne ayant le poids le plus élevé est celle qui sera appliquée en priorité.
Exemple :
div#conteneurId div.content{ background:red; } #conteneurId #contentId{ background:green; }
- La première chaine de sélection vaut : div 1+ #conteneurId 100 + div 1 + .content 10 = 102
- La seconde vaut : #conteneur 100 + #contentId 100 = 200
C’est donc la seconde qui s’appliquera.
Toutes les informations à ce sujet sur le site de la W3C : Priority level of selector
Il y est indiqué aussi que les instructions CSS présentent dans le HTML via l’attribut style de la balise ont un poids de 1000.
Évidemment, lisant ça je me suis demandé si une instruction css pouvait réellement prendre priorité sur une instruction dans l’attribut style de la balise. Bon, ça demande de pouvoir cibler assez profondément mais… Testons !
1000 = 10*100, il me faut au moins 10 niveaux avec id :
<!DOCTYPE html> <html> <body> <div id="niveau1"> <div id="niveau2"> <div id="niveau3"> <div id="niveau4"> <div id="niveau5"> <div id="niveau6"> <div id="niveau7"> <div id="niveau8"> <div id="niveau9"> <div id="niveau10" style="background-color: red"> Test </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </body> </html>
Et la CSS :
body div#niveau1 div#niveau2 div#niveau3 div#niveau4 div#niveau5 div#niveau6 div#niveau7 div#niveau8 div#niveau9 div#niveau10{ background-color: green; }
Bein… ça n’a pas marché malgré un poids de 1011 pour ma chaîne CSS qui est supérieure aux 1000 de l’attribut style… Le !important dans la feuille CSS fonctionne bien cela dit pour outrepasser l’attribut style.
Pour tester : http://jsfiddle.net/ERV6r/
Cela dit, si pour les milliers (attribut style dans la balise) ça ne marche pas, pour le reste c’est concluant. Et bon à savoir !
Leave a Reply