Kodokon kodokon.com

Variables CSS et fonctions calc/clamp

Maîtrisez les custom properties, leur résolution à l'exécution dans la cascade, et les fonctions calc() et clamp() pour des interfaces fluides.

10 min · 3 questions

Ouvrir cette leçon dans Kodokon

Les custom properties ne sont pas des variables de préprocesseur. Une variable Sass est remplacée à la compilation ; une propriété --brand est résolue à l'exécution, participe à la cascade, s'hérite comme n'importe quelle propriété et peut être modifiée par une media query, une classe ou JavaScript via setProperty(). C'est ce qui rend possibles le theming dynamique, le dark mode sans recompilation et la communication CSS/JS sans re-render.

CSS
:root {
  --brand: #6c5ce7;
  --spacing: 8px;
}

.card {
  color: var(--brand);
  padding: calc(var(--spacing) * 2);
  border-color: var(--accent, currentColor);
}
Déclaration, lecture et valeur de repli

Le deuxième argument de var() est une valeur de repli, utilisée uniquement si la propriété n'est pas définie. Piège classique : si --accent vaut 12px et que vous l'injectez dans color, le repli n'est pas utilisé. La déclaration devient invalide au moment du calcul de la valeur (invalid at computed-value time) : la propriété retombe sur sa valeur héritée ou initiale, et non sur la déclaration précédente comme le ferait une erreur de syntaxe classique.

La règle @property corrige deux limites majeures : elle donne un type à la variable (donc une validation) et la rend animable, puisque le moteur sait désormais interpoler entre deux valeurs typées au lieu de traiter la variable comme une chaîne opaque.

CSS
@property --progress {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 0%;
}

.gauge {
  background: conic-gradient(
    var(--brand) var(--progress),
    #e5e7eb 0
  );
  transition: --progress 0.4s ease-out;
}

.gauge.is-full {
  --progress: 100%;
}
Variable typée et animable avec @property

Côté calculs, calc() autorise le mélange d'unités (calc(100% - 2rem)), impossible avec un préprocesseur puisque la résolution dépend du contexte de rendu. clamp(min, ideal, max) est du sucre pour max(min, min(ideal, max)) et remplace avantageusement des séries de breakpoints pour la typographie fluide : la valeur idéale, souvent exprimée en vw ou cqi, glisse librement entre les deux bornes.

CSS
:root {
  --fluid-title: clamp(
    1.5rem,
    1rem + 2.5vw,
    3rem
  );
}

h1 {
  font-size: var(--fluid-title);
  max-width: clamp(20ch, 60%, 65ch);
}
Typographie fluide sans media query

Quiz de validation

Vérifiez que vous avez bien retenu les points clés de cette leçon.

  1. Que se passe-t-il si color: var(--gap) est évalué alors que --gap vaut 12px ?
    • La déclaration est ignorée et la règle color précédente s'applique
    • La déclaration devient invalide au calcul et color se résout comme unset
    • Le navigateur convertit 12px en couleur proche du noir
    • Une erreur est levée dans la console et la feuille est rejetée
  2. À quoi clamp(1rem, 2.5vw, 2rem) est-il strictement équivalent ?
    • max(1rem, min(2.5vw, 2rem))
    • min(1rem, max(2.5vw, 2rem))
    • calc(1rem + 2.5vw + 2rem)
  3. Quel apport principal de @property par rapport à une custom property classique ?
    • Elle rend la variable accessible depuis JavaScript
    • Elle permet d'utiliser la variable dans un calc()
    • Elle type la variable, ce qui la rend notamment interpolable en animation
    • Elle force l'héritage de la variable dans tout le document