16# Cascade de propriétés
Dans une feuille de style, il est possible que certaines propriétés entrent en concurrence : c’est à dire que deux valeurs différentes sont assignées pour une même propriété et un même élément. CSS introduit un mécanisme permettant de déterminer la valeur qui sera retenue, selon la spécificité du sélecteur de la règle.
Sur cette page :
- Cascade de propriétés
Voici un exemple très simple et très courant de concurrence entre deux règles :
p { color: blue; } .error { color: red; }
Ici, la première règle demande que tous les paragraphes soient en bleu, tandis que la seconde demande que tous les éléments de classe error soient en rouge. Le choix final n’est pas arbitraire, et la priorité est accordée selon un certain nombre de critères.
16.1# Les niveaux de priorité
il existe deux niveaux de priorité en CSS : le niveau normal, c’est à dire celui par défaut, et le niveau important, à définir manuellement pour chaque propriété qui doit être prioritaire. Utilisez le modificateur !important pour chaque propriété à modifier :
p { color: blue !important; }
15.2# Les cascades
Lorsque le moteur de rendu du navigateur traite les styles CSS, il devra utiliser trois sources :
- les styles par défaut du navigateur (User agent declarations)
- les styles définis par l’utilisateur (User defined declarations), qui correspondent à des modifications des styles par défaut du navigateur effectuées par un utilisateur (par exemple, une taille de police par défaut plus grande)
- les styles définis par l’intégrateur (Author declarations), c’est à dire, les feuilles de styles que vous avez créé.
Ainsi, les propriétés sont traitées dans cet ordre croissant de priorité :
- Les styles normaux du navigateur sont les moins prioritaires,
- les styles importants du navigateur,
- les styles normaux de l’utilisateur,
- les styles normaux de l’auteur,
- les styles importants de l’auteur,
- les styles importants définis par l’utilisateur sont les plus prioritaires.
Il est fort probable qu’après ce tri, des propriétés soient toujours en concurrence, notamment dans vos propres feuilles de styles. Dans ce cas, la priorité sera déterminée en fonction de la spécificité du sélecteur de la règle, et enfin, si deux règles ne peuvent être départagées, la dernière propriété évaluée aura la priorité.
16.3# Spécificité des sélecteurs
Le mécanisme de spécificité des sélecteurs permet de calculer de manière formelle la portée d’un sélecteur ou d’une combinaison. Par exemple, un sélecteur basé sur un identifiant est très spécifique, puisqu’il n’identifie qu’un élément dans la page, tandis qu’un sélecteur basé sur la nature d’un élément est très général.
Le calcul s’effectue selon un système de coefficients : chaque type de sélecteur possède une valeur, la spécificité est calculée en faisant la somme des valeurs obtenues. Plus la valeur obtenue est importante, plus le sélecteur ou la combinaison est spécifique, et plus la règle sera prioritaire.
- L’utilisation de l’attribut HTML
styleest totalement sélectif, car il ne concerne qu’un seul élément, sa valeur est 1000, (a) - l’utilisation d’un sélecteur par identifiant (par exemple
#mon_elt) vaut 100, (b) - l’utilisation d’un sélecteur par classe, d’un sélecteur par attribut, ou d’une pseudo-classe vaut 10, (c)
- l’utilisation d’un sélecteur par nature d’élément ou d’un pseudo-élément vaut 1, (d)
- enfin, le sélecteur universel vaut tout simplement 0.
Une petite subtilité peut attirer votre attention : le calcul de spécificité est lié à la forme du sélecteur et non à son sens, par exemple le sélecteur #mon_elt et *[id=mon_elt] sont équivalents, mais le premier aura une spécificité de 100, tandis que le second aura une spécificité estimée à 10. Veillez également à ne pas confondre les pseudo-classes et les pseudo-éléments !
Lorsque des sélecteurs sont combinés, leurs valeurs sont additionnées pour obtenir la spécificité de cette combinaison.
Voici quelques exemples (plus ou moins tordus) de calculs de spécificité :
*: 0p: 1a:first-letter: 2*1 = 2a:link: 10 + 1 = 11ul li: 2*1 = 2ul ol+li: 3*1 = 3* + a[hreflang=en]: 10 + 1 + 0 = 11p.error: 10 + 1 = 11.error= 10#mon_elt= 100p#mon_elt.error > span= 100 + 10 + 2*1 = 112style="": 1000
En réalité, le problème est un peu plus compliqué dans la mesure où plus de 9 sélecteurs du même coefficient sont utilisés dans une même combinaison, mais ceci reste très rare, je vous conseille donc d’adopter le mode de calcul que nous avons étudié jusqu’à présent. Cependant, pour ne pas mentir vis-à-vis des spécifications, voici la méthode de calcul complète :
Comptez le nombre de sélecteur de chaque catégorie de pondération (a, b, c et d). On considère que la valeur la plus importante de ces quatre nombre est n. La spécificité d’un sélecteur est calculée ainsi : a*n3 + b*n2 + c*n1 + c*n0. Les plus matheux d’entre vous auront reconnus qu’en fait, la valeur de la spécificité correspond à la concaténation des nombres a, b, c et d exprimé en base n. Si cette explication vous a donné mal à la tête, dites vous qu’il est rare que la méthode proposée précédemment ne fonctionne pas, puisque vous n’utiliserez probablement jamais une combinaison faisant appel à plus de 10 sélecteurs d’une catégorie !
Pour en savoir plus sur le mécanisme de cascade, je vous invite à consulter la section sur ce sujet de la recommandation officielle.
