CSS
Cascade et spécificité
Recherche…
Remarques
La spécificité CSS vise à favoriser la concision du code en permettant à un auteur de définir des règles de mise en forme générales pour un large ensemble d'éléments, puis de les remplacer pour un certain sous-ensemble.
En cascade
La cascade et la spécificité sont utilisées ensemble pour déterminer la valeur finale d'une propriété de style CSS. Ils définissent également les mécanismes de résolution des conflits dans les jeux de règles CSS.
Ordre de chargement CSS
Les styles sont lus à partir des sources suivantes, dans cet ordre:
- Feuille de style de l'agent utilisateur (styles fournis par le fournisseur du navigateur)
- Feuille de style utilisateur (le style supplémentaire défini par l'utilisateur sur son navigateur)
- Feuille de style de l'auteur (Auteur signifie le créateur de la page Web / du site Web)
- Peut-être un ou plusieurs fichiers
.css
- Dans l'élément
<style>
du document HTML
- Peut-être un ou plusieurs fichiers
- Styles en ligne (dans l'attribut de
style
sur un élément HTML)
Le navigateur recherchera les styles correspondants lors du rendu d'un élément.
Comment les conflits sont-ils résolus?
Lorsqu'un seul ensemble de règles CSS tente de définir un style pour un élément, il n'y a pas de conflit et ce jeu de règles est utilisé.
Lorsque plusieurs jeux de règles sont détectés avec des paramètres en conflit, commencez par définir les règles de spécification, puis les règles en cascade pour déterminer le style à utiliser.
Exemple 1 - Règles de spécificité
.mystyle { color: blue; } /* specificity: 0, 0, 1, 0 */
div { color: red; } /* specificity: 0, 0, 0, 1 */
<div class="mystyle">Hello World</div>
Quelle couleur sera le texte? (survolez pour voir la réponse)
bleu
Tout d'abord, les règles de spécificité sont appliquées et celle qui présente la plus grande spécificité "gagne".
Exemple 2 - Règles en cascade avec sélecteurs identiques
Fichier css externe
.class {
background: #FFF;
}
CSS interne (en fichier HTML)
<style>
.class {
background: #000;
}
<style>
Dans ce cas, lorsque vous avez des sélecteurs identiques, la cascade intervient et détermine que le dernier chargé "gagne".
Exemple 3 - Règles en cascade après les règles de spécificité
body > .mystyle { background-color: blue; } /* specificity: 0, 0, 1, 1 */
.otherstyle > div { background-color: red; } /* specificity: 0, 0, 1, 1 */
<body class="otherstyle">
<div class="mystyle">Hello World</div>
</body>
De quelle couleur sera l'arrière-plan?
rouge
Après avoir appliqué les règles de spécificité, il existe toujours un conflit entre le bleu et le rouge, de sorte que les règles en cascade sont appliquées en plus des règles de spécificité. La mise en cascade examine l'ordre de chargement des règles, que ce soit dans le même fichier .css
ou dans la collection de sources de style. Le dernier chargé remplace les précédents. Dans ce cas, la règle .otherstyle > div
"gagne".
Une note finale
- La spécificité du sélecteur prime toujours.
- Les feuilles de style ordonnent les cravates.
- Les styles en ligne l'emportent sur tout.
La déclaration! Importante
La déclaration !important
est utilisée pour remplacer la spécificité habituelle dans une feuille de style en donnant une priorité plus élevée à une règle. Son usage est: property : value !important;
#mydiv {
font-weight: bold !important; /* This property won't be overridden
by the rule below */
}
#outerdiv #mydiv {
font-weight: normal; /* #mydiv font-weight won't be set to normal
even if it has a higher specificity because
of the !important declaration above */
}
Eviter l'utilisation de !important
est fortement recommandé (sauf en cas d'absolue nécessité), car cela perturbera le flux naturel des règles CSS qui peuvent entraîner une incertitude dans votre feuille de style. En outre, il est important de noter que lorsque plusieurs déclarations !important
sont appliquées à la même règle sur un élément donné, la plus spécifique sera celle qui sera appliquée.
Voici quelques exemples où l'utilisation de !important
Déclaration !important
peut être justifiée:
- Si vos règles ne doivent pas être remplacées par un style en ligne de l'élément écrit dans l'attribut de
style
de l'élément html. - Pour donner à l'utilisateur plus de contrôle sur l'accessibilité du Web, comme augmenter ou diminuer la taille de la taille de la police, en remplaçant le style d'auteur par
!important
. - Pour tester et déboguer en utilisant l'élément inspect.
Voir également:
Calcul de la spécificité du sélecteur
Chaque sélecteur CSS individuel a sa propre valeur de spécificité. Chaque sélecteur dans une séquence augmente la spécificité globale de la séquence. Les sélecteurs appartiennent à l'un des trois groupes de spécificités suivants: A , B et c . Lorsque plusieurs séquences de sélecteur sélectionnent un élément donné, le navigateur utilise les styles appliqués par la séquence avec la spécificité globale la plus élevée.
Groupe | Composé de | Exemples |
---|---|---|
UNE | sélecteurs d'identification | #foo |
B | sélecteurs de classe sélecteurs d'attribut pseudo-classes | .bar [title] , [colspan="2"] :hover :nth-child(2) |
c | sélecteurs de type pseudo-éléments | div , li ::before , ::first-letter |
Le groupe A est le plus spécifique, suivi du groupe B , puis enfin du groupe c .
Le sélecteur universel ( *
) et les combinateurs (comme >
et ~
) n'ont pas de spécificité.
Exemple 1: Spécificité de différentes séquences de sélecteurs
#foo #baz {} /* a=2, b=0, c=0 */
#foo.bar {} /* a=1, b=1, c=0 */
#foo {} /* a=1, b=0, c=0 */
.bar:hover {} /* a=0, b=2, c=0 */
div.bar {} /* a=0, b=1, c=1 */
:hover {} /* a=0, b=1, c=0 */
[title] {} /* a=0, b=1, c=0 */
.bar {} /* a=0, b=1, c=0 */
div ul + li {} /* a=0, b=0, c=3 */
p::after {} /* a=0, b=0, c=2 */
*::before {} /* a=0, b=0, c=1 */
::before {} /* a=0, b=0, c=1 */
div {} /* a=0, b=0, c=1 */
* {} /* a=0, b=0, c=0 */
Exemple 2: Comment la spécificité est utilisée par le navigateur
Imaginez l'implémentation CSS suivante:
#foo {
color: blue;
}
.bar {
color: red;
background: black;
}
Nous avons ici un sélecteur d'ID qui déclare la color
en bleu et un sélecteur de classe qui déclare la color
en rouge et l' background
- background
en noir .
Un élément avec un ID de #foo
et une classe de .bar
sera sélectionné par les deux déclarations. Les sélecteurs d'ID ont une spécificité pour le groupe A et les sélecteurs de classe ont une spécificité pour le groupe B. Un sélecteur d'ID l'emporte sur un nombre quelconque de sélecteurs de classe. Pour cette raison, color:blue;
depuis le sélecteur #foo
et l' background:black;
- background:black;
du sélecteur .bar
sera appliqué à l'élément. La plus grande spécificité du sélecteur d'ID entraînera le navigateur à ignorer la .bar
de color
du sélecteur .bar
.
Imaginez maintenant une implémentation CSS différente:
.bar {
color: red;
background: black;
}
.baz {
background: white;
}
Ici, nous avons deux sélecteurs de classe; l'un d'eux déclare la color
en rouge et l' background
- background
en noir et l'autre déclare l' background
en blanc .
Un élément à la fois avec les classes .bar
et .baz
sera affecté par ces deux déclarations, mais le problème actuel est que les deux .bar
et .baz
ont une spécificité de groupe B identique. La nature en cascade de CSS résout ce problème pour nous: comme .baz
est défini après .bar
, notre élément se retrouve avec la color
rouge de .bar
mais le background
blanc de .baz
.
Exemple 3: Comment manipuler la spécificité
Le dernier extrait de l'exemple 2 ci-dessus peut être manipulé pour garantir que la déclaration de color
notre sélecteur de classe .bar
est utilisée à la place de celle du sélecteur de classe .baz
.
.bar {} /* a=0, b=1, c=0 */
.baz {} /* a=0, b=1, c=0 */
La manière la plus courante d'y parvenir serait de savoir quels autres sélecteurs peuvent être appliqués à la séquence de sélecteur .bar
. Par exemple, si la .bar
classe ne fut jamais appliquée pour span
des éléments, nous pourrions modifier le .bar
sélecteur span.bar
. Cela lui donnerait une nouvelle spécificité du groupe C , qui outrepasserait le .baz
sélecteur .baz
:
span.bar {} /* a=0, b=1, c=1 */
.baz {} /* a=0, b=1, c=0 */
Cependant, il n'est pas toujours possible de trouver un autre sélecteur commun qui est partagé entre tous les éléments utilisant la classe .bar
. Pour cette raison, CSS nous permet de dupliquer les sélecteurs pour augmenter la spécificité. Au lieu de simplement .bar
, nous pouvons utiliser .bar.bar
place (Voir La grammaire des sélecteurs, Recommandation du W3C ). Cela sélectionne toujours n'importe quel élément avec une classe de .bar
, mais a maintenant le double de la spécificité du groupe B :
.bar.bar {} /* a=0, b=2, c=0 */
.baz {} /* a=0, b=1, c=0 */
!important
déclarations de style !important
et en ligne
Le drapeau !important
sur une déclaration de style et les styles déclarés par l'attribut de style
HTML sont considérés comme ayant une plus grande spécificité que n'importe quel sélecteur. Si elles existent, la déclaration de style qu'elles affectent remplacera les autres déclarations, quelle que soit leur spécificité. C'est-à-dire, sauf si vous avez plus d'une déclaration contenant un indicateur !important
pour la même propriété qui s'applique au même élément. Ensuite, les règles de spécificité normales s'appliqueront à ces propriétés en référence les unes aux autres.
Parce qu'ils remplacent complètement la spécificité, l'utilisation de !important
est mal vue dans la plupart des cas d'utilisation. On devrait l'utiliser le moins possible. Pour que le code CSS soit efficace et maintenable à long terme, il est presque toujours préférable d'augmenter la spécificité du sélecteur environnant plutôt que d'utiliser !important
.
Une de ces rares exceptions où !important
n'est pas mal vu, est l'implémentation de classes d'assistance génériques comme une .hidden
ou .background-yellow
censées toujours remplacer une ou plusieurs propriétés où qu'elles soient rencontrées. Et même alors, vous devez savoir ce que vous faites. La dernière chose que vous voulez, lorsque vous écrivez des CSS maintenables, est d'avoir !important
indicateurs !important
dans votre CSS.
Une note finale
Une idée fausse commune à propos de la spécificité des CSS est que les valeurs des groupes A , B et c doivent être combinées entre elles ( a=1, b=5, c=1
=> 151). Ce n'est pas le cas. Si tel était le cas, il serait suffisant d'avoir 20 de sélecteur de groupe B ou c pour remplacer un seul sélecteur de groupe A ou B , respectivement. Les trois groupes doivent être considérés comme des niveaux de spécificité individuels. La spécificité ne peut être représentée par une seule valeur.
Lors de la création de votre feuille de style CSS, vous devez conserver la spécificité la plus faible possible. Si vous devez améliorer la spécificité pour remplacer une autre méthode, augmentez-la, mais aussi faible que possible pour la rendre plus élevée. Vous ne devriez pas avoir besoin d'un sélecteur comme celui-ci:
body.page header.container nav div#main-nav li a {}
Cela rend les changements futurs plus difficiles et pollue cette page CSS.
Vous pouvez calculer la spécificité de votre sélecteur ici
Exemple de spécificité plus complexe
div {
font-size: 7px;
border: 3px dotted pink;
background-color: yellow;
color: purple;
}
body.mystyle > div.myotherstyle {
font-size: 11px;
background-color: green;
}
#elmnt1 {
font-size: 24px;
border-color: red;
}
.mystyle .myotherstyle {
font-size: 16px;
background-color: black;
color: red;
}
<body class="mystyle">
<div id="elmnt1" class="myotherstyle">
Hello, world!
</div>
</body>
Quelles frontières, couleurs et tailles de police le texte sera-t-il?
taille de police:
font-size: 24;
#elmnt1
jeu de règles#elmnt1
a la spécificité la plus élevée pour le<div>
en question, chaque propriété est définie ici.
frontière:
border: 3px dotted red;
. La couleur de bordurered
est extraite du#elmnt1
règles#elmnt1
, car elle possède la plus grande spécificité. Les autres propriétés de la bordure, de l'épaisseur de la bordure et du style de bordure proviennent du jeu de règlesdiv
.
Couleur de fond:
background-color: green;
. Labackground-color
est définie dans lesbody.mystyle > div.myotherstyle
div
,body.mystyle > div.myotherstyle
et.mystyle .myotherstyle
. Les spécificités sont (0, 0, 1) vs (0, 2, 2) vs (0, 2, 0), donc le milieu "gagne".
Couleur:
color: red;
. La couleur est définie à la fois dans les jeux de règlesdiv
et.mystyle .myotherstyle
. Ce dernier a la spécificité la plus élevée de (0, 2, 0) et "gagne".