Il est temps de commencer à utiliser les propriétés personnalisées CSS

Publié: 2022-03-10
Résumé rapide ↬ Aujourd'hui, les préprocesseurs CSS sont un standard pour le développement web. L'un des principaux avantages des préprocesseurs est qu'ils vous permettent d'utiliser des variables. Cela vous aide à éviter de copier et coller du code, et cela simplifie le développement et la refactorisation.

Nous utilisons des préprocesseurs pour stocker les couleurs, les préférences de police, les détails de mise en page - principalement tout ce que nous utilisons en CSS.

Une introduction détaillée aux éléments personnalisés

Vous avez probablement entendu parler des composants Web et de la façon dont ils vont changer à jamais le développement Web. La technologie la plus transformatrice est celle des éléments personnalisés, une méthode de définition de vos propres éléments, avec leur propre comportement et propriétés. Lire la présentation →

Mais les variables de préprocesseur ont certaines limitations :

  • Vous ne pouvez pas les modifier dynamiquement.
  • Ils ne connaissent pas la structure du DOM.
  • Ils ne peuvent pas être lus ou modifiés à partir de JavaScript.

Comme solution miracle à ces problèmes et à d'autres, la communauté a inventé les propriétés personnalisées CSS. Essentiellement, celles-ci ressemblent et fonctionnent comme des variables CSS, et la façon dont elles fonctionnent se reflète dans leur nom.

Les propriétés personnalisées ouvrent de nouveaux horizons pour le développement Web.

Plus après saut! Continuez à lire ci-dessous ↓

Syntaxe pour déclarer et utiliser les propriétés personnalisées

Le problème habituel lorsque vous démarrez avec un nouveau préprocesseur ou framework est que vous devez apprendre une nouvelle syntaxe.

Chaque préprocesseur nécessite une manière différente de déclarer les variables. Habituellement, il commence par un symbole réservé - par exemple, $ dans Sass et @ dans LESS.

Les propriétés personnalisées CSS ont suivi le même chemin et utilisent -​- pour introduire une déclaration. Mais la bonne chose ici est que vous pouvez apprendre cette syntaxe une fois et la réutiliser dans tous les navigateurs !

Vous vous demandez peut-être « Pourquoi ne pas réutiliser une syntaxe existante ? »

Il y a une raison. En bref, il s'agit de fournir un moyen d'utiliser des propriétés personnalisées dans n'importe quel préprocesseur. De cette façon, nous pouvons fournir et utiliser des propriétés personnalisées, et notre préprocesseur ne les compilera pas, de sorte que les propriétés iront directement au CSS généré. Et , vous pouvez réutiliser les variables de préprocesseur dans les variables natives, mais je décrirai cela plus tard.

(En ce qui concerne le nom : parce que leurs idées et leurs objectifs sont très similaires, les propriétés personnalisées sont parfois appelées les variables CSS, bien que le nom correct soit les propriétés personnalisées CSS, et en lisant plus loin, vous comprendrez pourquoi ce nom les décrit le mieux.)

Ainsi, pour déclarer une variable au lieu d'une propriété CSS habituelle telle que color ou padding , fournissez simplement une propriété nommée personnalisée qui commence par -​- :

 .box{ --box-color: #4d4e53; --box-padding: 0 10px; }

La valeur d'une propriété peut être n'importe quelle valeur CSS valide : une couleur, une chaîne, une valeur de mise en page, voire une expression.

Voici des exemples de propriétés personnalisées valides :

 :root{ --main-color: #4d4e53; --main-bg: rgb(255, 255, 255); --logo-border-color: rebeccapurple; --header-height: 68px; --content-padding: 10px 20px; --base-line-height: 1.428571429; --transition-duration: .35s; --external-link: "external link"; --margin-top: calc(2vh + 20px); /* Valid CSS custom properties can be reused later in, say, JavaScript. */ --foo: if(x > 5) this.width = 10; }

Si vous n'êtes pas sûr de ce à quoi correspond :root , en HTML c'est la même chose que html mais avec une spécificité plus élevée.

Comme pour les autres propriétés CSS, les propriétés personnalisées se cascadent de la même manière et sont dynamiques. Cela signifie qu'ils peuvent être modifiés à tout moment et que la modification est traitée en conséquence par le navigateur.

Pour utiliser une variable, vous devez utiliser la fonction CSS var() et fournir le nom de la propriété à l'intérieur :

 .box{ --box-color:#4d4e53; --box-padding: 0 10px; padding: var(--box-padding); } .box div{ color: var(--box-color); }

Déclaration et cas d'utilisation

La fonction var() est un moyen pratique de fournir une valeur par défaut. Vous pouvez le faire si vous n'êtes pas sûr qu'une propriété personnalisée ait été définie et que vous souhaitez fournir une valeur à utiliser comme solution de secours. Cela peut être fait facilement en passant le second paramètre à la fonction :

 .box{ --box-color:#4d4e53; --box-padding: 0 10px; /* 10px is used because --box-margin is not defined. */ margin: var(--box-margin, 10px); }

Comme vous vous en doutez, vous pouvez réutiliser d'autres variables pour en déclarer de nouvelles :

 .box{ /* The --main-padding variable is used if --box-padding is not defined. */ padding: var(--box-padding, var(--main-padding)); --box-text: 'This is my box'; /* Equal to --box-highlight-text:'This is my box with highlight'; */ --box-highlight-text: var(--box-text)' with highlight'; }

Opérations : +, -, *, /

Comme nous nous sommes habitués aux préprocesseurs et à d'autres langages, nous voulons pouvoir utiliser des opérateurs de base lorsque nous travaillons avec des variables. Pour cela, CSS fournit une fonction calc() , qui oblige le navigateur à recalculer une expression après toute modification apportée à la valeur d'une propriété personnalisée :

 :root{ --indent-size: 10px; --indent-xl: calc(2*var(--indent-size)); --indent-l: calc(var(--indent-size) + 2px); --indent-s: calc(var(--indent-size) - 2px); --indent-xs: calc(var(--indent-size)/2); }

Un problème vous attend si vous essayez d'utiliser une valeur sans unité. Encore une fois, calc() est votre ami, car sans lui, cela ne fonctionnera pas :

 :root{ --spacer: 10; } .box{ padding: var(--spacer)px 0; /* DOESN'T work */ padding: calc(var(--spacer)*1px) 0; /* WORKS */ }

Portée et héritage

Avant de parler des étendues de propriétés personnalisées CSS, rappelons les étendues de JavaScript et du préprocesseur, pour mieux comprendre les différences.

On sait qu'avec, par exemple, des variables JavaScript ( var ), une portée est limitée aux fonctions.

Nous avons une situation similaire avec let et const , mais ce sont des variables locales de portée de bloc.

Une closure en JavaScript est une fonction qui a accès aux variables de la fonction externe (englobante) - la chaîne de portée. La fermeture a trois chaînes de portée, et elle a accès aux éléments suivants :

  • sa propre portée (c'est-à-dire les variables définies entre ses accolades),
  • les variables de la fonction externe,
  • les variables globales.

(Voir la grande version)

L'histoire avec les préprocesseurs est similaire. Prenons Sass comme exemple car c'est probablement le préprocesseur le plus populaire aujourd'hui.

Avec Sass, nous avons deux types de variables : locales et globales.

Une variable globale peut être déclarée en dehors de tout sélecteur ou construction (par exemple, en tant que mixin). Sinon, la variable serait locale.

Tous les blocs de code imbriqués peuvent accéder aux variables englobantes (comme en JavaScript).

(Voir la grande version)

Cela signifie que, dans Sass, les portées de la variable dépendent entièrement de la structure du code.

Cependant, les propriétés personnalisées CSS sont héritées par défaut et, comme les autres propriétés CSS, elles se succèdent.

Vous ne pouvez pas non plus avoir une variable globale qui déclare une propriété personnalisée en dehors d'un sélecteur - ce n'est pas un CSS valide. La portée globale des propriétés personnalisées CSS est en fait la portée :root , après quoi la propriété est disponible globalement.

Utilisons nos connaissances en syntaxe et adaptons l'exemple Sass à HTML et CSS. Nous allons créer une démo à l'aide des propriétés personnalisées CSS natives. Tout d'abord, le HTML :

 global <div class="enclosing"> enclosing <div class="closure"> closure </div> </div>

Et voici le CSS :

 :root { --globalVar: 10px; } .enclosing { --enclosingVar: 20px; } .enclosing .closure { --closureVar: 30px; font-size: calc(var(--closureVar) + var(--enclosingVar) + var(--globalVar)); /* 60px for now */ } 

Voir le Pen css-custom-properties-time-to-start-using 1 par Serg Hospodarets (@malyw) sur CodePen.

Voir le Pen css-custom-properties-time-to-start-using 1 par Serg Hospodarets (@malyw) sur CodePen.

Les modifications apportées aux propriétés personnalisées sont immédiatement appliquées à toutes les instances

Jusqu'à présent, nous n'avons pas vu en quoi cela diffère des variables Sass. Cependant, réaffectons la variable après son utilisation :

Dans le cas de Sass, cela n'a aucun effet :

 .closure { $closureVar: 30px; // local variable font-size: $closureVar +$enclosingVar+ $globalVar; // 60px, $closureVar: 30px is used $closureVar: 50px; // local variable } 

Voir le Pen css-custom-properties-time-to-start-using 3 par Serg Hospodarets (@malyw) sur CodePen.

Voir le Pen css-custom-properties-time-to-start-using 3 par Serg Hospodarets (@malyw) sur CodePen.

Mais en CSS, la valeur calculée est modifiée, car la valeur font-size est recalculée à partir de la valeur modifiée –closureVar :

 .enclosing .closure { --closureVar: 30px; font-size: calc(var(--closureVar) + var(--enclosingVar) + var(--globalVar)); /* 80px for now, --closureVar: 50px is used */ --closureVar: 50px; } 

Voir le Pen css-custom-properties-time-to-start-using 2 par Serg Hospodarets (@malyw) sur CodePen.

Voir le Pen css-custom-properties-time-to-start-using 2 par Serg Hospodarets (@malyw) sur CodePen.

C'est la première grande différence : si vous réaffectez la valeur d'une propriété personnalisée, le navigateur recalculera toutes les variables et expressions calc() là où elle est appliquée.

Les préprocesseurs ne connaissent pas la structure du DOM

Supposons que nous voulions utiliser la font-size par défaut pour le bloc, sauf là où la classe highlighted est présente.

Voici le HTML :

 <div class="default"> default </div> <div class="default highlighted"> default highlighted </div>

Faisons cela en utilisant les propriétés personnalisées CSS :

 .highlighted { --highlighted-size: 30px; } .default { --default-size: 10px; /* Use default-size, except when highlighted-size is provided. */ font-size: var(--highlighted-size, var(--default-size)); }

Étant donné que le deuxième élément HTML avec la classe default porte la classe en highlighted , les propriétés de la classe en highlighted seront appliquées à cet élément.

Dans ce cas, cela signifie que –highlighted-size: 30px; sera appliqué, ce qui fera que la propriété font-size assignée utilisera –highlighted-size .

Tout est simple et fonctionne :

Voir le Pen css-custom-properties-time-to-start-using 4 par Serg Hospodarets (@malyw) sur CodePen.

Voir le Pen css-custom-properties-time-to-start-using 4 par Serg Hospodarets (@malyw) sur CodePen.

Maintenant, essayons d'obtenir la même chose en utilisant Sass :

 .highlighted { $highlighted-size: 30px; } .default { $default-size: 10px; /* Use default-size, except when highlighted-size is provided. */ @if variable-exists(highlighted-size) { font-size: $highlighted-size; } @else { font-size: $default-size; } }

Le résultat montre que la taille par défaut est appliquée à la fois :

Voir le Pen css-custom-properties-time-to-start-using 5 par Serg Hospodarets (@malyw) sur CodePen.

Voir le Pen css-custom-properties-time-to-start-using 5 par Serg Hospodarets (@malyw) sur CodePen.

Cela se produit parce que tous les calculs et traitements Sass se produisent au moment de la compilation, et bien sûr, il ne sait rien de la structure du DOM, s'appuyant entièrement sur la structure du code.

Comme vous pouvez le voir, les propriétés personnalisées ont les avantages de la portée des variables et ajoutent la cascade habituelle des propriétés CSS, en étant conscientes de la structure du DOM et en suivant les mêmes règles que les autres propriétés CSS.

Le deuxième point à retenir est que les propriétés personnalisées CSS sont conscientes de la structure du DOM et sont dynamiques .

Mots-clés à l'échelle du CSS et all propriétés

Les propriétés personnalisées CSS sont soumises aux mêmes règles que les propriétés personnalisées CSS habituelles. Cela signifie que vous pouvez leur attribuer n'importe lequel des mots-clés CSS courants :

  • inherit
    Ce mot-clé CSS applique la valeur du parent de l'élément.
  • initial
    Cela applique la valeur initiale telle que définie dans la spécification CSS (une valeur vide, ou rien dans certains cas de propriétés personnalisées CSS).
  • unset
    Cela applique la valeur héritée si une propriété est normalement héritée (comme dans le cas des propriétés personnalisées) ou la valeur initiale si la propriété n'est normalement pas héritée.
  • revert
    Cela réinitialise la propriété à la valeur par défaut établie par la feuille de style de l'agent utilisateur (une valeur vide dans le cas des propriétés personnalisées CSS).

Voici un exemple:

 .common-values{ --border: inherit; --bgcolor: initial; --padding: unset; --animation: revert; }

Considérons un autre cas. Supposons que vous souhaitiez créer un composant et que vous vouliez vous assurer qu'aucun autre style ou propriété personnalisée ne lui soit appliqué par inadvertance (une solution CSS modulaire serait généralement utilisée pour les styles dans un tel cas).

Mais maintenant, il existe un autre moyen : utiliser la propriété CSS all . Ce raccourci réinitialise toutes les propriétés CSS.

Avec les mots-clés CSS, nous pouvons faire ce qui suit :

 .my-wonderful-clean-component{ all: initial; }

Cela a réinitialisé tous les styles de notre composant.

Malheureusement, le mot clé all ne réinitialise pas les propriétés personnalisées. Il y a une discussion en cours sur l'opportunité d'ajouter le préfixe -​- , ce qui réinitialiserait toutes les propriétés personnalisées CSS.

Ainsi, à l'avenir, une réinitialisation complète pourrait être effectuée comme ceci :

 .my-wonderful-clean-component{ --: initial; /* reset all CSS custom properties */ all: initial; /* reset all other CSS styles */ }

Cas d'utilisation des propriétés personnalisées CSS

Il existe de nombreuses utilisations des propriétés personnalisées. Je vais montrer les plus intéressants d'entre eux.

Émuler des règles CSS inexistantes

Le nom de ces variables CSS est "propriétés personnalisées", alors pourquoi ne pas les utiliser pour émuler des propriétés inexistantes ?

Il y en a beaucoup : translateX/Y/Z , background-repeat-x/y (toujours pas compatible avec tous les navigateurs), box-shadow-color .

Essayons de faire fonctionner le dernier. Dans notre exemple, changeons la couleur de l'ombre de la boîte au survol. Nous voulons simplement suivre la règle DRY (ne vous répétez pas), donc au lieu de répéter la valeur entière de box-shadow dans la section :hover , nous allons simplement changer sa couleur. Propriétés personnalisées à la rescousse :

 .test { --box-shadow-color: yellow; box-shadow: 0 0 30px var(--box-shadow-color); } .test:hover { --box-shadow-color: orange; /* Instead of: box-shadow: 0 0 30px orange; */ } 

Voir la propriété CSS Pen Emulating "box-shadow-color" à l'aide des propriétés personnalisées CSS par Serg Hospodarets (@malyw) sur CodePen.

Voir la propriété CSS "box-shadow-color" d'émulation du stylet à l'aide des propriétés personnalisées CSS par Serg Hospodarets (@malyw) sur CodePen.

Thèmes de couleur

L'un des cas d'utilisation les plus courants des propriétés personnalisées concerne les thèmes de couleur dans les applications. Des propriétés personnalisées ont été créées pour résoudre ce type de problème. Fournissons donc un thème de couleur simple pour un composant (les mêmes étapes pourraient être suivies pour une application).

Voici le code de notre composant bouton :

 .btn { background-image: linear-gradient(to bottom, #3498db, #2980b9); text-shadow: 1px 1px 3px #777; box-shadow: 0px 1px 3px #777; border-radius: 28px; color: #ffffff; padding: 10px 20px 10px 20px; }

Supposons que nous voulions inverser le thème de couleur.

La première étape serait d'étendre toutes les variables de couleur aux propriétés personnalisées CSS et de réécrire notre composant. Donc le résultat serait le même :

 .btn { --shadow-color: #777; --gradient-from-color: #3498db; --gradient-to-color: #2980b9; --color: #ffffff; background-image: linear-gradient( to bottom, var(--gradient-from-color), var(--gradient-to-color) ); text-shadow: 1px 1px 3px var(--shadow-color); box-shadow: 0px 1px 3px var(--shadow-color); border-radius: 28px; color: var(--color); padding: 10px 20px 10px 20px; }

Cela a tout ce dont nous avons besoin. Avec lui, nous pouvons remplacer les variables de couleur par les valeurs inversées et les appliquer si nécessaire. Nous pourrions, par exemple, ajouter la classe HTML inverted globale (à, disons, l'élément body ) et changer les couleurs lorsqu'elle est appliquée :

 body.inverted .btn{ --shadow-color: #888888; --gradient-from-color: #CB6724; --gradient-to-color: #D67F46; --color: #000000; }

Vous trouverez ci-dessous une démo dans laquelle vous pouvez cliquer sur un bouton pour ajouter et supprimer une classe globale :

Voir le Pen css-custom-properties-time-to-start-using 9 par Serg Hospodarets (@malyw) sur CodePen.

Voir le Pen css-custom-properties-time-to-start-using 9 par Serg Hospodarets (@malyw) sur CodePen.

Ce comportement ne peut pas être atteint dans un préprocesseur CSS sans la surcharge de code dupliqué. Avec un préprocesseur, vous auriez toujours besoin de remplacer les valeurs et les règles réelles, ce qui entraîne toujours un CSS supplémentaire.

Avec les propriétés personnalisées CSS, la solution est aussi propre que possible, et le copier-coller est évité, car seules les valeurs des variables sont redéfinies.

Utiliser des propriétés personnalisées avec JavaScript

Auparavant, pour envoyer des données de CSS vers JavaScript, nous devions souvent recourir à des astuces, en écrivant des valeurs CSS via du JSON brut dans la sortie CSS, puis en les lisant à partir du JavaScript.

Désormais, nous pouvons facilement interagir avec les variables CSS à partir de JavaScript, en les lisant et en les écrivant à l'aide des méthodes bien connues .getPropertyValue() et .setProperty() , qui sont utilisées pour les propriétés CSS habituelles :

 /** * Gives a CSS custom property value applied at the element * element {Element} * varName {String} without '--' * * For example: * readCssVar(document.querySelector('.box'), 'color'); */ function readCssVar(element, varName){ const elementStyles = getComputedStyle(element); return elementStyles.getPropertyValue(`--${varName}`).trim(); } /** * Writes a CSS custom property value at the element * element {Element} * varName {String} without '--' * * For example: * readCssVar(document.querySelector('.box'), 'color', 'white'); */ function writeCssVar(element, varName, value){ return element.style.setProperty(`--${varName}`, value); }

Supposons que nous ayons une liste de valeurs de requête multimédia :

 .breakpoints-data { --phone: 480px; --tablet: 800px; }

Parce que nous ne voulons les réutiliser qu'en JavaScript — par exemple, dans Window.matchMedia() — nous pouvons facilement les obtenir depuis CSS :

 const breakpointsData = document.querySelector('.breakpoints-data'); // GET const phoneBreakpoint = getComputedStyle(breakpointsData) .getPropertyValue('--phone');

Pour montrer comment attribuer des propriétés personnalisées à partir de JavaScript, j'ai créé une démonstration interactive de cube CSS 3D qui répond aux actions de l'utilisateur.

Ce n'est pas très difficile. Nous avons juste besoin d'ajouter un arrière-plan simple, puis de placer cinq faces de cube avec les valeurs pertinentes pour la propriété de transform : translateZ() , translateY() , rotateX() et rotateY() .

Pour fournir la bonne perspective, j'ai ajouté ce qui suit au wrapper de page :

 #world{ --translateZ:0; --rotateX:65; --rotateY:0; transform-style:preserve-3d; transform: translateZ(calc(var(--translateZ) * 1px)) rotateX(calc(var(--rotateX) * 1deg)) rotateY(calc(var(--rotateY) * 1deg)); }

La seule chose qui manque, c'est l'interactivité. La démo doit modifier les angles de vue X et Y ( –rotateX et –rotateY ) lorsque la souris se déplace et doit effectuer un zoom avant et arrière lorsque la souris défile ( –translateZ ).

Voici le JavaScript qui fait l'affaire :

 // Events onMouseMove(e) { this.worldXAngle = (.5 - (e.clientY / window.innerHeight)) * 180; this.worldYAngle = -(.5 - (e.clientX / window.innerWidth)) * 180; this.updateView(); }; onMouseWheel(e) { /*…*/ this.worldZ += delta * 5; this.updateView(); }; // JavaScript -> CSS updateView() { this.worldEl.style.setProperty('--translateZ', this.worldZ); this.worldEl.style.setProperty('--rotateX', this.worldXAngle); this.worldEl.style.setProperty('--rotateY', this.worldYAngle); };

Désormais, lorsque l'utilisateur déplace sa souris, la démo change la vue. Vous pouvez vérifier cela en déplaçant votre souris et en utilisant la molette de la souris pour zoomer et dézoomer :

Voir le Pen css-custom-properties-time-to-start-using 10 par Serg Hospodarets (@malyw) sur CodePen.

Voir le Pen css-custom-properties-time-to-start-using 10 par Serg Hospodarets (@malyw) sur CodePen.

Essentiellement, nous venons de modifier les valeurs des propriétés personnalisées CSS. Tout le reste (la rotation et le zoom avant et arrière) est fait par CSS.

Conseil : L'un des moyens les plus simples de déboguer une valeur de propriété personnalisée CSS consiste simplement à afficher son contenu dans le contenu généré par CSS (ce qui fonctionne dans des cas simples, comme avec des chaînes), afin que le navigateur affiche automatiquement la valeur appliquée actuelle :

 body:after { content: '--screen-category : 'var(--screen-category); }

Vous pouvez le vérifier dans la démo CSS simple (pas de HTML ni de JavaScript). (Redimensionnez la fenêtre pour voir le navigateur refléter automatiquement la valeur de la propriété personnalisée CSS modifiée.)

Prise en charge du navigateur

Les propriétés personnalisées CSS sont prises en charge dans tous les principaux navigateurs :

(Voir la grande version)

Cela signifie que vous pouvez commencer à les utiliser nativement.

Si vous avez besoin de prendre en charge des navigateurs plus anciens, vous pouvez apprendre la syntaxe et les exemples d'utilisation et envisager des moyens possibles de basculer ou d'utiliser des variables CSS et de préprocesseur en parallèle.

Bien sûr, nous devons être en mesure de détecter la prise en charge à la fois dans CSS et JavaScript afin de fournir des solutions de secours ou des améliorations.

C'est assez facile. Pour CSS, vous pouvez utiliser une condition @supports avec une requête de fonctionnalité factice :

 @supports ( (--a: 0)) { /* supported */ } @supports ( not (--a: 0)) { /* not supported */ }

En JavaScript, vous pouvez utiliser la même propriété personnalisée factice avec la méthode statique CSS.supports() :

 const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--a', 0); if (isSupported) { /* supported */ } else { /* not supported */ }

Comme nous l'avons vu, les propriétés personnalisées CSS ne sont toujours pas disponibles dans tous les navigateurs. Sachant cela, vous pouvez progressivement améliorer votre application en vérifiant si elles sont prises en charge.

Par exemple, vous pouvez générer deux fichiers CSS principaux : un avec des propriétés personnalisées CSS et un second sans elles, dans lequel les propriétés sont en ligne (nous discuterons des moyens de le faire sous peu).

Chargez le second par défaut. Ensuite, faites simplement une vérification dans JavaScript et passez à la version améliorée si les propriétés personnalisées sont prises en charge :

 <!-- HTML --> <link href="without-css-custom-properties.css" rel="stylesheet" type="text/css" media="all" />
 // JavaScript if(isSupported){ removeCss('without-css-custom-properties.css'); loadCss('css-custom-properties.css'); // + conditionally apply some application enhancements // using the custom properties }

C'est juste un exemple. Comme vous le verrez ci-dessous, il existe de meilleures options.

Comment commencer à les utiliser

Selon une enquête récente, Sass continue d'être le préprocesseur de choix pour la communauté du développement.

Examinons donc les moyens de commencer à utiliser les propriétés personnalisées CSS ou de s'y préparer à l'aide de Sass.

Nous avons quelques options.

1. Vérifier manuellement le code pour le support

L'un des avantages de cette méthode de vérification manuelle dans le code si les propriétés personnalisées sont prises en charge est qu'elle fonctionne et que nous pouvons le faire dès maintenant (n'oubliez pas que nous sommes passés à Sass) :

 $color: red; :root { --color: red; } .box { @supports ( (--a: 0)) { color: var(--color); } @supports ( not (--a: 0)) { color: $color; } }

Cette méthode présente de nombreux inconvénients, dont le moindre n'est pas que le code se complique et que le copier-coller devient assez difficile à maintenir.

2. Utilisez un plugin qui traite automatiquement le CSS résultant

L'écosystème PostCSS fournit aujourd'hui des dizaines de plugins. Quelques-uns d'entre eux traitent les propriétés personnalisées (valeurs en ligne) dans la sortie CSS résultante et les font fonctionner, en supposant que vous ne fournissez que des variables globales (c'est-à-dire que vous ne déclarez ou ne modifiez que les propriétés personnalisées CSS à l'intérieur du(s) sélecteur(s) :root ), donc leurs valeurs peut être facilement aligné.

Un exemple est postcss-custom-properties.

Ce plugin offre plusieurs avantages : il fait fonctionner la syntaxe ; il est compatible avec toute l'infrastructure de PostCSS ; et il ne nécessite pas beaucoup de configuration.

Il y a cependant des inconvénients. Le plugin nécessite que vous utilisiez des propriétés personnalisées CSS, vous n'avez donc pas de chemin pour préparer votre projet pour un changement de variables Sass. De plus, vous n'aurez pas beaucoup de contrôle sur la transformation, car elle est effectuée après la compilation de Sass en CSS. Enfin, le plugin ne fournit pas beaucoup d'informations de débogage.

3. Mixin css-vars

J'ai commencé à utiliser les propriétés personnalisées CSS dans la plupart de mes projets et j'ai essayé de nombreuses stratégies :

  • Passez de Sass à PostCSS avec cssnext.
  • Passez des variables Sass aux propriétés personnalisées CSS pures.
  • Utilisez des variables CSS dans Sass pour détecter si elles sont prises en charge.

À la suite de cette expérience, j'ai commencé à chercher une solution qui satisferait mes critères :

  • Il devrait être facile de commencer à utiliser Sass.
  • Il doit être simple à utiliser et la syntaxe doit être aussi proche que possible des propriétés personnalisées CSS natives.
  • Basculer la sortie CSS des valeurs en ligne vers les variables CSS devrait être facile.
  • Un membre de l'équipe qui connaît les propriétés personnalisées CSS pourrait utiliser la solution.
  • Il devrait y avoir un moyen d'avoir des informations de débogage sur les cas extrêmes dans l'utilisation des variables.

Du coup, j'ai créé css-vars, un mixin Sass que vous pouvez trouver sur Github. En l'utilisant, vous pouvez en quelque sorte commencer à utiliser la syntaxe des propriétés personnalisées CSS.

Utilisation de css-vars Mixin

Pour déclarer des variable(s), utilisez le mixin comme suit :

 $white-color: #fff; $base-font-size: 10px; @include css-vars(( --main-color: #000, --main-bg: $white-color, --main-font-size: 1.5*$base-font-size, --padding-top: calc(2vh + 20px) ));

Pour utiliser ces variables, utilisez la fonction var() :

 body { color: var(--main-color); background: var(--main-bg, #f00); font-size: var(--main-font-size); padding: var(--padding-top) 0 10px; }

Cela vous donne un moyen de contrôler toute la sortie CSS à partir d'un seul endroit (depuis Sass) et de commencer à vous familiariser avec la syntaxe. De plus, vous pouvez réutiliser les variables et la logique Sass avec le mixin.

Lorsque tous les navigateurs que vous souhaitez prendre en charge fonctionnent avec des variables CSS, il vous suffit d'ajouter ceci :

 $css-vars-use-native: true;

Au lieu d'aligner les propriétés de la variable dans le CSS résultant, le mixin commencera à enregistrer les propriétés personnalisées et les instances var() iront au CSS résultant sans aucune transformation. Cela signifie que vous serez entièrement passé aux propriétés personnalisées CSS et que vous bénéficierez de tous les avantages dont nous avons parlé.

Si vous souhaitez activer les informations de débogage utiles, ajoutez ce qui suit :

 $css-vars-debug-log: true;

Cela vous donnera :

  • un journal lorsqu'une variable n'a pas été affectée mais a été utilisée ;
  • un journal lorsqu'une variable est réaffectée ;
  • informations lorsqu'une variable n'est pas définie mais qu'une valeur par défaut est transmise et utilisée à la place.

Conclusion

Vous en savez maintenant plus sur les propriétés personnalisées CSS, y compris leur syntaxe, leurs avantages, de bons exemples d'utilisation et comment interagir avec elles à partir de JavaScript.

Vous avez appris à détecter si elles sont prises en charge, en quoi elles diffèrent des variables de préprocesseur CSS et à commencer à utiliser des variables CSS natives jusqu'à ce qu'elles soient prises en charge par tous les navigateurs.

C'est le bon moment pour commencer à utiliser les propriétés personnalisées CSS et se préparer à leur prise en charge native dans les navigateurs.