The CSS Podcast - 003: Specificity
Supposons que vous utilisiez le code HTML et CSS suivant:
<button class="branding">Hello, Specificity!</button>
.branding {
color: blue;
}
button {
color: red;
}
Ici, deux règles ciblent le même élément. Chaque règle contient une déclaration qui souhaite définir la couleur du bouton : l'une tente de le colorer en rouge et l'autre en bleu. Quelle déclaration est appliquée à l'élément ?
Comprendre l'algorithme de spécificité CSS est essentiel pour comprendre comment le CSS choisit entre les déclarations concurrentes.
La spécificité est l'une des étapes distinctes de la cascade, qui a été abordée dans le dernier module sur la cascade.
Évaluation de la spécificité
Chaque règle de sélecteur dans une origine reçoit un score. Vous pouvez considérer la spécificité comme un score total, et chaque type de sélecteur gagne des points pour ce score. Les déclarations des règles les plus spécifiques l'emportent.
Dans un projet réel, l'équilibre consiste à s'assurer que les règles CSS que vous prévoyez d'appliquer s'appliquent, tout en gardant généralement les scores bas pour éviter la complexité. La spécificité ne doit être aussi élevée que nécessaire, plutôt que de viser la plus grande spécificité possible. À l'avenir, il se peut que vous deviez appliquer des styles CSS plus importants. Si vous optez pour la plus grande spécificité, vous compliquerez cette tâche.
La spécificité n'est pas un nombre décimal, mais une triade composée de trois composants: A
, B
et C
.
A
: spécificité semblable à un IDB
: spécificité semblable à une classeC
: spécificité semblable à un élément
Il est souvent représenté à l'aide de la notation (A,B,C)
. Exemple : (1,0,2)
.
La notation A-B-C
est également couramment utilisée.
Comparer les spécificités
Les spécificités sont comparées en comparant les trois composants dans l'ordre suivant : la spécificité avec une valeur A plus élevée est plus spécifique ; si les deux valeurs A sont identiques, la spécificité avec une valeur B plus élevée est plus spécifique ; si les deux valeurs B sont également identiques, la spécificité avec une valeur C plus élevée est plus spécifique ; si toutes les valeurs sont identiques, les deux spécificités sont égales.
Par exemple, (1,0,0)
est considéré comme plus spécifique que (0,4,3)
, car la valeur A
dans (1,0,0)
(qui est 1
) est supérieure à la valeur A
de (0,4,3)
(qui est 0
).
Les sélecteurs ont une influence sur la spécificité.
Chaque partie de la triade de spécificité commence par une valeur de 0
. La spécificité par défaut est donc (0,0,0)
.
Chaque partie d'un sélecteur augmente la spécificité qui, en fonction du type de sélecteur, augmente la valeur de A
, B
ou C
.
Sélecteur universel
Un sélecteur universel (*
) n'ajoute aucune spécificité, laissant sa valeur à la spécificité initiale de (0,0,0)
.
* {
color: red;
}
Sélecteur d'élément ou de pseudo-élément
Un sélecteur d'élément (type) ou de pseudo-élément ajoute une spécificité semblable à celle d'un élément, ce qui augmente le composant C
de 1
.
Les exemples suivants ont une spécificité globale de (0,0,1)
.
Sélecteur de type
div {
color: red;
}
Sélecteur de pseudo-éléments
::selection {
color: red;
}
Sélecteur de classe, de pseudo-classe ou d'attribut
Un sélecteur de classe, de pseudo-classe ou d'attribut ajoute une spécificité semblable à une classe, qui augmente le composant B
de 1
.
Les exemples suivants ont une spécificité de (0,1,0)
.
Sélecteur de classe
.my-class {
color: red;
}
Sélecteur de classe pseudo
:hover {
color: red;
}
Sélecteur d'attribut
[href='#'] {
color: red;
}
Sélecteur d'ID
Un sélecteur d'ID ajoute une spécificité semblable à un ID, ce qui augmente le composant C
de 1, à condition que vous utilisiez un sélecteur d'ID (#myID
) et non un sélecteur d'attribut ([id="myID"]
).
Dans l'exemple suivant, la spécificité est (1,0,0)
.
#myID {
color: red;
}
Autres sélecteurs
Le CSS comporte de nombreux sélecteurs. Ils ne sont pas tous spécifiques.
Par exemple, la pseudo-classe :not()
n'ajoute rien au calcul de la spécificité.
Toutefois, les sélecteurs transmis en tant qu'arguments sont ajoutés au calcul de la spécificité.
div:not(.my-class) {
color: red;
}
Cet exemple a une spécificité de (0,1,1), car il comporte un sélecteur de type (div
) et une classe à l'intérieur de :not()
.
Vérifier vos connaissances
Tester vos connaissances sur le score de spécificité
Quelle est la spécificité de a[href="#"]
?
(0,0,1)
a
vaut (0,0,1)
, mais [href="#"]
vaut (0,1,0)
.(0,1,0)
a
vaut (0,0,1)
, mais [href="#"]
vaut (0,1,0)
.(0,1,1)
a
vaut (0,0,1)
et [href="#"]
vaut (0,1,1)
, ce qui donne une spécificité totale de (0,1,1)
.Facteurs n'ayant aucune incidence sur la spécificité
Voici quelques idées reçues courantes sur les facteurs suivants qui affectent la spécificité.
Attributs de style intégrés
Le CSS appliqué directement à l'attribut style
d'un élément n'a aucune incidence sur la spécificité, car il s'agit d'une étape différente de la cascade qui est évaluée avant la spécificité.
<div style="color: red"></div>
Pour remplacer cette déclaration à partir d'une feuille de style, vous devez obtenir la victoire de la déclaration à une étape antérieure de la cascade.
Par exemple, vous pouvez y ajouter !important
pour qu'il fasse partie de l'origine !important
créée par l'auteur.
!important
déclarations
Un !important
à la fin d'une déclaration CSS n'affecte pas la spécificité, mais place la déclaration dans une origine différente, à savoir !important
créé.
Dans l'exemple suivant, la spécificité de .my-class
n'est pas pertinente pour que la déclaration !important
l'emporte.
.my-class {
color: red !important;
color: white;
}
Lorsque deux déclarations sont !important
, la spécificité entre à nouveau en jeu, car l'étape d'origine de la cascade n'a pas encore pu déterminer le gagnant.
.branding {
color: blue !important;
}
button {
color: red !important;
}
Spécificité dans le contexte
Lorsqu'un sélecteur complexe ou composé est utilisé, chaque partie de ce sélecteur s'ajoute à la spécificité. Prenons l'exemple HTML suivant:
<a class="my-class another-class" href="#">A link</a>
Ce lien comporte deux classes.
La règle du CSS suivant a une spécificité de (0,0,1)
:
a {
color: red;
}
Si vous faites référence à l'une des classes du sélecteur, elle a désormais une spécificité de (0,1,1)
:
a.my-class {
color: green;
}
Ajoutez l'autre classe au sélecteur. Il a désormais une spécificité de (0,2,1)
:
a.my-class.another-class {
color: rebeccapurple;
}
Ajoutez l'attribut href
au sélecteur. Il dispose désormais d'une spécificité de (0,3,1)
:
a.my-class.another-class[href] {
color: goldenrod;
}
Enfin, ajoutez une pseudo-classe :hover
à tout cela. Le sélecteur se termine par une spécificité de (0,4,1)
:
a.my-class.another-class[href]:hover {
color: lightgrey;
}
Vérifier vos connaissances
Tester vos connaissances sur le score de spécificité
Parmi les sélecteurs suivants, lequel a une spécificité de (0,2,1)
?
article > section
(0,0,2)
.article.card.dark
(0,2,1)
.article:hover a[href]
(0,0,1)
), un sélecteur d'attribut ((0,0,1)
) et un sélecteur de classe ((0,0,1)
). La spécificité totale de ce sélecteur est donc de (0,2,2)
.Augmenter de manière pragmatique la spécificité
Supposons que vous disposiez d'un code CSS qui se présente comme suit:
.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Avec du code HTML, cela se présente comme suit:
<button class="my-button" onclick="alert('hello')">Click me</button>
Le bouton a un arrière-plan gris, car le deuxième sélecteur a une spécificité de (0,1,1)
.
En effet, il comporte un sélecteur de type (button
), qui est (0,0,1)
, et un sélecteur d'attribut ([onclick]
), qui est (0,1,0)
.
La règle précédente (.my-button
) est égale à (0,1,0)
, car elle comporte un sélecteur de classe, ce qui est moins spécifique que (0,1,1)
.
Si vous souhaitez renforcer cette règle, vous pouvez répéter le sélecteur de classe comme suit:
.my-button.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Le bouton aura désormais un arrière-plan bleu, car le nouveau sélecteur reçoit une spécificité (0,2,0)
.
En cas d'égalité de spécificité, l'étape suivante de la cascade est appliquée.
Pour l'instant, restons sur l'exemple de bouton et remplaçons le code CSS par le suivant:
.my-button {
background: blue;
}
[onclick] {
background: grey;
}
Le bouton a un arrière-plan gris, car les deux sélecteurs ont une spécificité identique de (0,1,0)
.
Si vous inversez l'ordre des règles dans l'ordre source, le bouton devient bleu.
[onclick] {
background: grey;
}
.my-button {
background: blue;
}
En effet, les deux sélecteurs ont la même spécificité. Dans ce cas, la cascade revient à l'étape d'ordre d'apparition.