Cours CSS / variables : var(), portée, héritage et valeurs de repli
Les propriétés personnalisées CSS stockent des valeurs réutilisables et sont référencées avec var() dans les valeurs de propriété. Leur portée suit la cascade et l'héritage, et une valeur de repli de var() ne corrige pas automatiquement une valeur définie qui est invalide pour la propriété qui la reçoit.
Choisissez des variables partagées significatives
Si vous utilisez la même couleur d'accent pour plusieurs boutons et cartes, vous pouvez la regrouper dans une variable significative au lieu de copier le code couleur dans chaque sélecteur. Lors du changement de la couleur d'accent, si vous modifiez une déclaration, l'endroit qui fait référence à cette valeur change également. Si vous créez des variables, même pour des valeurs utilisées uniquement à un endroit et n'ayant aucun rôle distinct, le fardeau de devoir suivre les noms peut en réalité augmenter.
:root {
--accent: #1d5f91;
--space-unit: .5rem;
}
.button { color: white; background: var(--accent); }
.card { border: 2px solid var(--accent); padding: calc(var(--space-unit) * 3); }
Déclarer simplement une couleur dans le code ci-dessus ne change pas l'écran. Les propriétés comme background et border doivent utiliser var() pour référencer cette valeur. Si le nom indique le rôle, comme --accent, plutôt que de fixer la couleur actuelle, comme --blue, ce sera moins déroutant lors du changement vers une couleur différente plus tard. --accent et --Accent sont des noms différents, donc respectez la casse et l'orthographe.
var() s’utilise dans les valeurs de propriétés comme color ou padding. Cette fonction ne remplace ni les sélecteurs ni les noms de propriétés. Dans une condition de media query telle que @media (min-width: ...), le seuil ne peut pas être fourni avec var(). Il en va de même pour la valeur d’une condition de taille de conteneur. Écrivez les seuils dans les conditions et réservez les variables aux valeurs de propriétés auxquelles elles peuvent être substituées.
Comprendre la racine, l'héritage et la portée des composants
Dans un document HTML, :root correspond à l'élément HTML de niveau supérieur, il est donc pratique d'avoir une valeur par défaut commune dans le document. Les propriétés personnalisées communes -- sont héritées par les descendants. Les valeurs déclarées dans une carte peuvent être utilisées par les descendants, comme le titre, mais ne sont pas transmises aux cartes sœurs non liées.
.card { --card-accent: var(--accent); }
.card.warning { --card-accent: #a63e32; }
.card { border-color: var(--card-accent); }
.card h2 { color: var(--card-accent); }
Cette règle fait partie intégrante de l'exemple complet ci-dessous. .card.warning correspond aux cartes ayant les deux classes. Gagner ou perdre n'est pas déterminé par l'ordre de déclaration des classes HTML, mais en correspondant au règles d’héritage, de spécificité et de cascade CSS pour déterminer la valeur. Modifier l'accent global changera la carte par défaut, et les cartes d'avertissement avec leur propre accent-carte conserveront leurs couleurs d'avertissement d'origine.
Les références entre variables sont résolues sur l’élément où leur valeur est calculée, avant l’héritage. Si --line-color: var(--accent) est calculé sur le parent, l’enfant hérite de la valeur de --line-color déjà résolue. Redéfinir --accent sur l’enfant ne recalcule pas cette valeur héritée. Pour suivre l’accent local de l’enfant, déclarez la valeur dérivée sur cet enfant ou utilisez directement var(--accent) dans la propriété concernée. Consultez la Spécification des propriétés personnalisées CSS.
Distinguer les valeurs de secours et les valeurs calculées invalides
var(--notice-color, #6a3989) fournit une valeur de repli violette lorsqu'une valeur de variable est manquante et ne peut pas être utilisée. Même si une variable est définie et possède une valeur significative dans d'autres propriétés, telles que 20px, si la valeur ne correspond pas à une couleur, la déclaration de couleur devient invalide au moment du calcul. Dans ce cas, vous ne devez pas vous attendre à être « remplacé par le violet ».
| état de la variable | Résultat de la déclaration de couleur | Couleurs pour l'exemple entier |
|---|---|---|
| --notice-color non définie | Utilisation des valeurs de repli pour var | violet |
| --notice-color est une couleur rouge | Utiliser les valeurs définies | rouge |
| --notice-color vaut 20px | Les règles de valeur initiale/héritage sont appliquées parce qu'elle ne correspond pas à la couleur | Parce que la couleur est héritée, utilisez la couleur de texte verte du parent. |
Comme indiqué ci-dessous, même s'il y a d'abord une déclaration bleue dans la même règle, si la valeur après la substitution de variable dans la deuxième déclaration ne correspond pas, elle ne reviendra pas au premier bleu. Après que la déclaration sélectionnée dans la cascade est invalide au moment de l'évaluation, les règles d'héritage de la couleur sont appliquées. Dans la même situation, une propriété qui n'est pas héritée peut être traitée comme la valeur initiale de cette propriété. Le guide MDN des propriétés personnalisées explique la différence entre les valeurs de remplacement et les valeurs invalides.
.sample {
color: #1d5f91;
color: var(--notice-color, #6a3989);
}
.sample.bad { --notice-color: 20px; }
Vous pouvez également mettre d'autres variables dans la valeur de repli. Par exemple, var(--button-accent, var(--accent, #1d5f91)) recherche la valeur à utiliser, en commençant par la valeur spécifique au bouton, puis la valeur commune, et enfin la couleur principale. Cependant, si l'utilisation des nombres, des longueurs et des couleurs est mélangée, le même problème se produit, donc les noms de variables et l'utilisation doivent être gérés ensemble.
Combinez les valeurs et les unités avec calc()
L'exemple multiplie --space-unit: .5rem par 3 pour définir le padding de la carte. rem utilise la taille de police de la racine, donc modifier cette taille change l'espacement. Utilisez calc() pour le calcul plutôt que de concaténer des chaînes, et laissez des espaces autour des opérateurs d'addition et de soustraction. Pour plus de détails, voir Couleurs et unités CSS : px, em, rem et pourcentages.
:root {
--space-unit: .5rem;
--space-card: calc(var(--space-unit) * 3);
}
.card { padding: var(--space-card); }
Choisissez systématiquement si les variables incluent des unités ou uniquement des nombres. Si vous saisissez une valeur sans unité telle que 2 dans la variable de longueur, elle peut ne pas convenir aux applications nécessitant des unités. Évitez les combinaisons d’utilisations différentes, comme appliquer calc à une variable contenant une couleur. Pour la syntaxe de base de la formule, consultez le document MDN calc.
Exécutez la comparaison de portée et de repli
Enregistrez le code suivant sous le nom custom-properties.html en UTF-8 et ouvrez-le dans votre navigateur. Comparez les couleurs d’accentuation des deux cartes et les couleurs de texte des trois phrases. La signification des couleurs a également été écrite en lettres afin que les résultats ne puissent pas être distingués uniquement par la couleur.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CSS variable scope and substitution values</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; padding: 1rem; color: #183044; font-family: sans-serif; line-height: 1.6; }
main { max-width: 46rem; margin-inline: auto; }
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
button, input { font: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #164f73; outline-offset: 3px; }
:root { --space-unit: .5rem; --space-card: calc(var(--space-unit) * 3); --accent: #1d5f91; }
.cards { display: grid; gap: 1rem; }
.card { --card-accent: var(--accent); padding: var(--space-card); border: 2px solid var(--card-accent);
border-radius: .5rem; background: #f6f9fb; }
.card h2 { color: var(--card-accent); margin-block: 0 .5rem; }
.card p { margin: 0; }
.card.warning { --card-accent: #a63e32; }
.fallback-area { margin-block: 2rem; padding: 1rem; border: 1px solid #8a9ba7; color: #28633b; }
.sample { color: #1d5f91; color: var(--notice-color, #6a3989); }
.sample.bad { --notice-color: 20px; }
.sample.good { --notice-color: #a63e32; }
</style>
</head>
<body>
<main>
<h1>Variable scope and fallbacks</h1>
<div class="cards">
<article class="card"><h2>Basic card</h2><p>The heading and border share the same accent color.</p></article>
<article class="card warning"><h2>warning card</h2><p>The accent color changes only inside this card.</p></article>
</div>
<section class="fallback-area">
<h2>The parent's text color is green</h2>
<p class="sample missing">Undefined: purple fallback</p>
<p class="sample bad">20px: Doesn't match the color, so it inherits the green color from the parent.</p>
<p class="sample good">Defined as red: use that color</p>
</section>
</main>
</body>
</html>
- Assurez-vous que le titre et la bordure des cartes de base sont bleus et que les cartes d'avertissement sont rouges. Les trois phrases ci-dessous sont colorées en violet, vert et rouge, respectivement.
- Changez uniquement l'accent racine en
#28633b. Le titre et la bordure de la carte par défaut doivent changer, tandis que la carte d'avertissement conserve sa propre couleur d'avertissement. Restaurez l'accent racine en#1d5f91après vérification. - Remplacez uniquement --space-unit à la racine par
1rem. Les marges intérieures des deux cartes s'étendent ensemble. Après confirmation, restaurez à .5rem. - Dans .sample.bad, remplacez uniquement --notice-color de
20pxà#1d5f91. La phrase passera du vert au bleu. Après confirmation, restaurez-la à 20px. - Supprimez uniquement --notice-color dans .sample.bad. Cette fois, un repli violet est utilisé. Comparez avec le résultat bleu de l'étape précédente et restaurez la déclaration originale.
Diagnostiquer les variables manquantes ou incorrectes
- Dans les outils de développement, vérifiez si le nom de la variable et sa valeur existent réellement dans cet élément. Examinez d'abord l'orthographe, la capitalisation et la portée de la déclaration.
- Vérifiez si les descendants ou d'autres règles écrasent la même variable. Il se peut qu'il ne s'agisse pas d'une erreur pour un composant de conserver ses valeurs uniques même si sa valeur commune change.
- Vérifiez si la variable est référencée dans la propriété réelle et si les unités et le type de la valeur substituée sont corrects.
- Si une valeur est créée à travers plusieurs variables, vérifiez l'élément calculé et la valeur héritée. Évitez également les déclarations qui se réfèrent à la même variable qu'elles-mêmes ou qui se réfèrent circulairement.
Vous pouvez tirer parti des variables en distinguant les couleurs et les espacements communs du design et les exceptions pour chaque composant, et en vérifiant les résultats avant et après la modification. Plutôt que d'augmenter le nombre de noms de variables, il est plus utile pour la maintenance de clarifier quelles valeurs sont partagées dans quelle portée.




