Fermer

mai 14, 2018

Un guide de stratégie pour les propriétés personnalisées CSS


Les propriétés personnalisées CSS (parfois appelées 'variables CSS') sont maintenant supportées dans tous les navigateurs modernes, et les gens commencent à les utiliser en production. C'est génial, mais ils sont différents des variables dans les préprocesseurs, et j'ai déjà vu de nombreux exemples de personnes qui les utilisent sans considérer les avantages qu'ils offrent.

Les propriétés personnalisées ont un énorme potentiel pour changer la façon d'écrire et de structurer et dans une moindre mesure, comment nous utilisons JavaScript pour interagir avec les composants de l'interface utilisateur. Je ne vais pas me concentrer sur la syntaxe et comment ils fonctionnent (pour cela je vous recommande de lire " Il est temps de commencer à utiliser les propriétés personnalisées "). Au lieu de cela, je veux jeter un regard plus approfondi sur les stratégies pour tirer le meilleur parti des propriétés personnalisées CSS.

Les propriétés personnalisées sont un peu comme des variables dans les préprocesseurs, mais ont des différences importantes. La première et la plus évidente différence est la syntaxe.

Une différence importante entre les propriétés personnalisées et les variables dans les préprocesseurs est que les propriétés personnalisées ont une syntaxe différente pour attribuer une valeur et récupérer cette valeur. Lors de la récupération de la valeur d'une propriété personnalisée, nous utilisons la fonction var ()

La différence la plus évidente suivante est dans le nom. Ils sont appelés «propriétés personnalisées» car ce sont vraiment des propriétés CSS. Dans les préprocesseurs, vous pouvez déclarer et utiliser des variables presque n'importe où, y compris à l'extérieur des blocs de déclaration, dans les règles de média, ou même dans le cadre d'un sélecteur.

 $ breakpoint: 800px;
$ smashing-red: # d33a2c;
$ smashing-things: ".smashing-text, .cats";

Écran @media et (min-width: $ breakpoint) {
  # {$ smashing-things} {
    couleur: $ smashing-red;
  }
}

La ​​plupart des exemples ci-dessus ne seraient pas valides en utilisant des propriétés personnalisées

Les propriétés personnalisées ont les mêmes règles quant à l'endroit où elles peuvent être utilisées en tant que propriétés CSS normales. Il est préférable de les considérer comme des propriétés dynamiques plutôt que comme des variables. Cela signifie qu'ils ne peuvent être utilisés qu'à l'intérieur d'un bloc de déclaration, ou en d'autres termes, les propriétés personnalisées sont liées à un sélecteur. Cela peut être le sélecteur : root ou tout autre sélecteur valide

: root {--smashing-red: # d33a2c; }

Écran @media et (min-width: 800px) {
  .smashing-text, .cats {
    --marge-gauche: 1em;
  }
}

Vous pouvez récupérer la valeur d'une propriété personnalisée partout où vous utiliseriez une valeur dans une déclaration de propriété. Cela signifie qu'ils peuvent être utilisés comme une seule valeur, dans le cadre d'une déclaration abrégée ou même à l'intérieur des équations calc () .

 .smashing-text, .cats {
  couleur: var (- smashing-red);
  margin: 0 var (- marge-horizontale);
  padding: calc (var (- marge-horizontale) / 2)
}

Cependant, ils ne peuvent pas être utilisés dans les règles des médias, ou les sélecteurs y compris : nth-child () .

Il y a probablement beaucoup plus de choses à savoir sur la syntaxe et comment fonctionnent les propriétés personnalisées , comme comment utiliser les valeurs de repli et pouvez-vous attribuer des variables à d'autres variables (oui), mais cette introduction de base devrait suffire à comprendre le reste des concepts de cet article. Pour plus d'informations sur les spécificités du fonctionnement des propriétés personnalisées, vous pouvez lire " Il est temps de commencer à utiliser des propriétés personnalisées " écrit par Serg Hospodarets

Dynamique vs. Statique

La différence la plus significative entre les variables dans les préprocesseurs et les propriétés personnalisées est la manière dont elles sont définies. Nous pouvons nous référer aux variables comme étant statiquement ou dynamiquement. Les variables dans les préprocesseurs sont statiques alors que les propriétés personnalisées sont dynamiques.

Lorsque CSS est concerné static signifie que vous pouvez mettre à jour la valeur d'une variable à différents moments du processus de compilation, mais cela ne peut pas changer la valeur

 $ background: bleu;
.bleu {
  arrière-plan: $ background;
}
$ background: rouge;
.rouge {
  arrière-plan: $ background;
}

résultats en:

 .blue {
  fond: bleu;
}
.rouge {
  fond: rouge;
}

Une fois que cela est rendu à CSS, les variables ont disparu. Cela signifie que nous pourrions potentiellement lire un fichier .scss et déterminer sa sortie sans rien savoir sur le HTML, le navigateur ou d'autres entrées. Ce n'est pas le cas avec les propriétés personnalisées.

Les préprocesseurs ont une sorte de "portée de bloc" dans laquelle les variables peuvent être temporairement changées dans un sélecteur, une fonction ou un mixage. Cela modifie la valeur d'une variable à l'intérieur du bloc, mais elle est toujours statique. Ceci est lié au bloc, pas au sélecteur. Dans l'exemple ci-dessous, la variable $ background est modifiée dans le bloc .example . Il revient à la valeur initiale en dehors du bloc, même si nous utilisons le même sélecteur.

 $ background: red;
.Exemple {
  $ background: bleu;
  arrière-plan: $ background;
}

.Exemple {
  arrière-plan: $ background;
}

Cela aura pour résultat:

 .example {
  fond: bleu;
}
.Exemple {
  fond: rouge;
}

Les propriétés personnalisées fonctionnent différemment. Lorsque les propriétés personnalisées sont concernées, la portée dynamique signifie qu'elles sont soumises à l'héritage et à la cascade. La propriété est liée à un sélecteur et si la valeur change, ceci affecte tous les éléments DOM correspondants comme n'importe quelle autre propriété CSS.

C'est génial parce que vous pouvez changer la valeur d'une propriété personnalisée dans une requête multimédia, avec un pseudo sélecteur tel que hover, ou même avec JavaScript.

 a {
  --link-color: noir;
}
a: vol stationnaire,
a: focus {
  --link-color: tomate;
}
Écran @media et (min-width: 600px) {
  une {
    --link-color: bleu;
  }
}

une {
  couleur: var (- link-color);
}

Nous n'avons pas besoin de changer l'endroit où la propriété personnalisée est utilisée – nous changeons la valeur de la propriété personnalisée avec CSS. Cela signifie utiliser la même propriété personnalisée, nous pouvons avoir différentes valeurs dans différents endroits ou contextes sur la même page

Global vs. Local

En plus d'être statiques ou dynamiques, les variables peuvent aussi être globales ou locales. Si vous écrivez JavaScript, vous le saurez. Les variables peuvent être appliquées à tout dans une application, ou leur portée peut être limitée à des fonctions spécifiques ou à des blocs de code.

CSS est similaire. Nous avons certaines choses qui sont appliquées à l'échelle mondiale et d'autres qui sont plus locales. Les couleurs de la marque, l'espacement vertical et la typographie sont autant d'exemples de choses que vous pourriez vouloir appliquer de manière globale et cohérente sur votre site Web ou votre application. Nous avons aussi des choses locales. Par exemple, un composant de bouton peut avoir une variante petite et grande. Vous ne voudriez pas que les tailles de ces boutons soient appliquées à tous les éléments d'entrée ou même à tous les éléments de la page.

C'est quelque chose que nous connaissons en CSS. Nous avons développé des systèmes de conception, des conventions de nommage et des bibliothèques JavaScript, tous pour aider à isoler les composants locaux et les éléments de conception globaux. Les propriétés personnalisées fournissent de nouvelles options pour gérer ce problème ancien.

Les propriétés personnalisées CSS sont par défaut étendues localement aux sélecteurs spécifiques auxquels elles sont appliquées. Donc, ils sont un peu comme des variables locales. Cependant, les propriétés personnalisées sont également héritées, donc dans de nombreuses situations elles se comportent comme des variables globales – en particulier lorsqu'elles sont appliquées au sélecteur : root . Cela signifie que nous devons réfléchir à la manière de les utiliser.

De nombreux exemples montrent que des propriétés personnalisées sont appliquées à l'élément : root et bien que cette amende pour une démo puisse entraîner portée globale désordonnée et problèmes inattendus avec l'héritage. Heureusement, nous avons déjà appris ces leçons.

Les variables globales ont tendance à être statiques

Il existe quelques petites exceptions, mais en général, la plupart des choses globales dans CSS sont aussi statiques.

, la typographie et l'espacement n'ont pas tendance à changer beaucoup d'un composant à l'autre. Quand ils changent, cela tend à être un changement de marque global ou un autre changement important qui arrive rarement sur un produit mature. Il est toujours logique que ces choses soient des variables, elles sont utilisées dans de nombreux endroits, et les variables aident à la cohérence. Mais cela n'a pas de sens pour eux d'être dynamiques. La valeur de ces variables ne change pas de manière dynamique.

Pour cette raison, Je recommande fortement d'utiliser des préprocesseurs pour les variables globales (statiques). Cela garantit non seulement qu'ils sont toujours statiques, mais il les dénote visuellement dans le code. Cela peut rendre CSS beaucoup plus lisible et plus facile à maintenir.

Les variables statiques locales sont correctes (parfois)

On peut penser que les variables globales étant statiques, par réflexion, toutes les variables locales peuvent avoir besoin être dynamique. S'il est vrai que les variables locales tendent à être dynamiques, elles sont loin d'être aussi fortes que la tendance d'une variable globale à être statique.

Les variables statiques locales sont parfaitement correctes dans de nombreuses situations. J'utilise des variables de préprocesseurs dans les fichiers de composants principalement comme commodité de développeur

Considérons l'exemple classique d'un composant bouton avec plusieurs variations de taille


 buttons

My scss pourrait ressembler à ceci:

 $ button-sml: 1em;
$ button-med: 1.5em;
$ button-lrg: 2em;

.btn {
  // Styles visuels
}

.btn-sml {
  taille de police: $ button-sml;
}

.btn-med {
  taille de police: $ button-med;
}

.btn-lrg {
  taille de police: $ button-lrg;
}

Évidemment, cet exemple aurait plus de sens si j'utilisais les variables plusieurs fois ou si je dérivais des valeurs de marge et de remplissage à partir des variables de taille. Cependant, la capacité de prototyper rapidement des tailles différentes peut être une raison suffisante.

Parce que la plupart des variables statiques sont globales, j'aime différencier les variables statiques qui sont utilisées seulement dans un composant. Pour ce faire, vous pouvez préfixer ces variables avec le nom du composant, ou utiliser un autre préfixe comme c-variable-name pour le composant ou l-variable-name pour local. Vous pouvez utiliser n'importe quel préfixe, ou vous pouvez préfixer des variables globales. Quoi que vous choisissiez, il est utile de différencier notamment si vous convertissez une base de code existante pour utiliser les propriétés personnalisées

Quand utiliser les propriétés personnalisées

Si vous utilisez des variables statiques dans les composants, quand utiliser les propriétés personnalisées? La conversion de variables de préprocesseur existantes en propriétés personnalisées n'a généralement pas beaucoup de sens. Après tout, la raison de propriétés personnalisées est complètement différente. Les propriétés personnalisées ont du sens lorsque les propriétés CSS changent en fonction d'une condition dans le DOM, en particulier une condition dynamique telle que : focus : hover requêtes multimédias ou JavaScript. 19659008] Je pense que nous utiliserons toujours des variables statiques, bien que nous en aurions peut-être besoin à l'avenir, car les propriétés personnalisées offrent de nouvelles façons d'organiser la logique et le code. Jusque-là, je pense que dans la plupart des situations, nous allons travailler avec une combinaison de variables de préprocesseur et de propriétés personnalisées.

Il est utile de savoir que nous pouvons assigner des variables statiques à des propriétés personnalisées. Qu'elles soient globales ou locales, il est logique dans de nombreuses situations de convertir des variables statiques en propriétés personnalisées localement dynamiques

Note : Saviez-vous que $ var est une valeur valide pour une propriété personnalisée? Les versions récentes de Sass le reconnaissent et nous devons donc interpoler les variables assignées aux propriétés personnalisées, comme ceci: # {$ var} . Cela indique à Sass que vous voulez afficher la valeur de la variable, plutôt que seulement $ var dans la feuille de style. Ceci est seulement nécessaire pour des situations comme les propriétés personnalisées, où un nom de variable peut également être un CSS valide.

Si nous prenons l'exemple du bouton ci-dessus et décidons que tous les boutons doivent utiliser la petite variation sur les appareils mobiles. classe appliquée dans le HTML, c'est maintenant une situation plus dynamique. Pour cela, nous devrions utiliser des propriétés personnalisées.

 $ button-sml: 1em;
$ button-med: 1.5em;
$ button-lrg: 2em;

.btn {
  --button-size: # {$ bouton-sml};
}

Écran @media et (min-width: 600px) {
  .btn-med {
    --button-size: # {$ button-med};
  }
  .btn-lrg {
    --button-size: # {$ button-lrg};
  }
}

.btn {
  taille de police: var (- taille de bouton);
}

Ici, je crée une seule propriété personnalisée: - button-size . Cette propriété personnalisée est initialement étendue à tous les éléments de bouton à l'aide de la classe btn . Je change ensuite la valeur de - taille de bouton au-dessus de 600px pour les classes btn-med et btn-lrg . Enfin, j'applique cette propriété personnalisée à tous les éléments du bouton en un seul endroit

Ne soyez pas trop malin

La nature dynamique des propriétés personnalisées nous permet de créer des composants intelligents et compliqués.

préprocesseurs, beaucoup d'entre nous ont créé des bibliothèques avec des abstractions intelligentes en utilisant des mixins et des fonctions personnalisées. Dans des cas limités, des exemples comme celui-ci sont toujours utiles aujourd'hui, mais pour la plupart, plus je travaille avec les préprocesseurs, moins les fonctionnalités que j'utilise. Aujourd'hui, j'utilise presque exclusivement des préprocesseurs pour les variables statiques.

Les propriétés personnalisées ne seront pas (et ne devraient pas) être immunisées contre ce type d'expérimentation, et j'ai hâte de voir de nombreux exemples intelligents. Mais à long terme, le code lisible et maintenable l'emportera toujours sur des abstractions intelligentes (au moins en production).

J'ai lu récemment un excellent article sur ce sujet sur le Free Camp Camp Medium. Il a été écrit par Bill Sourour et s'appelle " Ne le faites pas à l'exécution. Faites-le au moment du design . "Plutôt que de paraphraser ses arguments, je vous laisse le lire.

Une différence essentielle entre les variables du préprocesseur et les propriétés personnalisées est que les propriétés personnalisées fonctionnent à l'exécution. Cela signifie que les choses qui auraient pu être acceptables en termes de complexité, avec les préprocesseurs pourraient ne pas être une bonne idée avec les propriétés personnalisées.

Voici un exemple qui illustre cela récemment pour moi:

: root {
  --font-échelle: 1.2;
  --font-size-1: calc (var (- font-échelle) * var (- font-size-2));
  --font-size-2: calc (var (- font-échelle) * var (- font-size-3));
  --font-size-3: calc (var (- font-échelle) * var (- font-size-4));
  --font-size-4: 1rem;
}

Ceci génère une échelle modulaire. Une échelle modulaire est une série de nombres qui se rapportent les uns aux autres en utilisant un ratio. Ils sont souvent utilisés dans la conception et le développement Web pour définir les tailles de police ou l'espacement.

Dans cet exemple, chaque propriété personnalisée est déterminée en utilisant calc () en prenant la valeur de la propriété personnalisée précédente et multipliant cela par le ratio. Pour ce faire, nous pouvons obtenir le nombre suivant dans l'échelle.

Cela signifie que les ratios sont calculés au moment de l'exécution et vous pouvez les modifier en mettant à jour uniquement la valeur de la propriété - police-échelle . Par exemple:

 écran @media et (min-width: 800px) {
  :racine {
    --Font échelle: 1,33;
  }
}

C'est intelligent, concis et beaucoup plus rapide que de calculer toutes les valeurs si vous voulez changer l'échelle. C'est aussi quelque chose que je ne ferais pas en code de production.

Bien que l'exemple ci-dessus soit utile pour le prototypage, en production, je préférerais de loin voir quelque chose comme ça:

: root {
  --font-size-1: 1.728rem;
  --font-size-2: 1.44rem;
  --font-size-3: 1.2em;
  --font-size-4: 1em;
}

Écran @media et (min-width: 800px) {
  :racine {
    --font-size-1: 2.369rem;
    --font-size-2: 1,777rem;
    --font-size-3: 1.333rem;
    --font-size-4: 1rem;
  }
}

Semblable à l'exemple de l'article de Bill, je trouve utile de voir quelles sont les valeurs réelles. Nous lisons le code beaucoup plus de fois que nous ne l'écrivons et les valeurs globales telles que les échelles de police changent rarement dans la production.

L'exemple ci-dessus n'est toujours pas parfait. Il viole la règle de plus tôt que les valeurs globales devraient être statiques . Je préférerais de beaucoup utiliser des variables de préprocesseur et les convertir en propriétés personnalisées dynamiques locales en utilisant les techniques démontrées précédemment.

Il est également important d'éviter les situations où l'on passe d'une propriété personnalisée à une propriété personnalisée différente. Cela peut se produire lorsque nous nommons des propriétés comme celle-ci.

Modifier la valeur non la variable

Modifier la valeur non la variable est l'une des stratégies les plus importantes pour utiliser efficacement les propriétés personnalisées.

ne devrait jamais changer quelle propriété personnalisée est utilisée pour un but unique.
C'est facile à faire parce que c'est exactement ce que nous faisons avec les préprocesseurs, mais cela n'a aucun sens avec les propriétés personnalisées.

Dans cet exemple, nous avons deux propriétés personnalisées qui sont utilisées sur un exemple de composant. Je passe de l'utilisation de la valeur de - font-size-small à - font-size-large en fonction de la taille de l'écran.

: root {
  --font-size-small: 1.2em;
  --font-size-large: 2em;
}
.Exemple {
  taille de police: var (- font-size-small);
}
Écran @media et (min-width: 800px) {
  .Exemple {
    taille de police: var (- font-size-large);
  }
}

Une meilleure façon de le faire serait de définir une seule propriété personnalisée portée au composant. Ensuite, en utilisant une requête multimédia ou un autre sélecteur, changez sa valeur.

 .example {
  --example-font-size: 1.2em;
}
Écran @media et (min-width: 800px) {
  .Exemple {
    --example-font-size: 2em;
  }
}

Enfin, en un seul endroit, j'utilise la valeur de cette propriété personnalisée:

 .example {
  taille de police: var (- example-font-size);
}

Dans cet exemple et d'autres avant celui-ci, les requêtes multimédias n'ont été utilisées que pour modifier la valeur des propriétés personnalisées. Vous pouvez également remarquer qu'il n'y a qu'un seul endroit où l'instruction var () est utilisée et les propriétés CSS normales sont mises à jour

Cette séparation entre les déclarations de variables et les déclarations de propriétés est intentionnelle. Il y a de nombreuses raisons à cela, mais les avantages sont plus évidents quand on pense au design responsive.

Conception adaptative avec propriétés personnalisées

L'une des difficultés du design responsive quand il dépend fortement des requêtes média est que peu importe comment vous organisez votre CSS, les styles relatifs à un composant particulier se fragmentent à travers la feuille de style.

Il peut être très difficile de savoir quelles propriétés CSS vont changer. Néanmoins, les propriétés personnalisées CSS peuvent nous aider à organiser certaines logiques liées à la conception réactive et faciliter le travail avec les requêtes média.

Si cela change une variable

Les propriétés qui utilisent les requêtes média sont intrinsèquement dynamiques et personnalisées Les propriétés fournissent les moyens d'exprimer des valeurs dynamiques dans CSS. Cela signifie que si vous utilisez une requête média pour modifier une propriété CSS, vous devez placer cette valeur dans une propriété personnalisée.

Vous pouvez ensuite déplacer ceci, avec toutes les règles de média, les états de survol ou les sélecteurs dynamiques définissant

Séparer la logique de la conception

Si elle est effectuée correctement, la séparation de la logique et de la conception signifie que les requêtes de support ne sont utilisées que pour modifier la valeur des propriétés personnalisées . Cela signifie que toute la logique liée au design responsive devrait être en haut du document, et partout où nous voyons une instruction var () dans notre CSS, nous savons immédiatement que cette propriété change. Avec les méthodes traditionnelles d'écriture de CSS, il n'y avait aucun moyen de le savoir d'un coup d'œil.

Beaucoup d'entre nous ont très bien lu et interprété les CSS en jetant un coup d'œil sur les propriétés changées dans différentes situations. J'en ai marre, et je ne veux plus faire ça! Les propriétés personnalisées fournissent maintenant un lien entre la logique et son implémentation, donc nous n'avons pas besoin de suivre cela, et c'est incroyablement utile!

The Logic Fold

L'idée de déclarer des variables en haut d'un document ou d'une fonction n'est pas une nouvelle idée. C'est quelque chose que nous faisons dans la plupart des langues, et c'est maintenant quelque chose que nous pouvons faire en CSS. Écrire CSS de cette manière crée une distinction visuelle claire entre CSS en haut du document et ci-dessous. J'ai besoin d'un moyen de différencier ces sections quand je parle d'eux et l'idée d'un "pli logique" est une métaphore que j'ai commencé à utiliser.
Au-dessus du pli contient toutes les variables du préprocesseur et les propriétés personnalisées. Cela inclut toutes les différentes valeurs qu'une propriété personnalisée peut avoir. Il devrait être facile de tracer comment une propriété personnalisée change.

CSS sous le pli est simple et hautement déclaratif et facile à lire. Il se sent comme CSS avant les requêtes de médias et d'autres complexités nécessaires de CSS moderne.

Jetez un oeil à un exemple très simple d'un système de grille flexbox six colonnes:

 .row {
  --row-display: bloquer;
}
Écran @media et (min-width: 600px) {
  .rangée {
    --row-display: flex;
  }
}

La ​​propriété personnalisée - row-display est initialement définie sur block. Au-dessus de 800px, le mode d'affichage est réglé pour fléchir.

Sous le pli pourrait ressembler à ceci:

 .row {
  display: var (- affichage des lignes);
  flex-direction: rangée;
  flex-wrap: maintenant
}
.col-1, .col-2, .col-3,
.col-4, .col-5, .col-6 {
  flex-grow: 0;
  flex-shrink: 0;
}
.col-1 {flex-basis: 16,66%; }
.col-2 {flex-basis: 33,33%; }
.col-3 {flex-basis: 50%; }
.col-4 {flex-basis: 66,66%; }
.col-5 {flex-basis: 83,33%; }
.col-6 {flex-basis: 100%; }

Nous savons immédiatement - row-display est une valeur qui change. Initialement, ce sera bloc donc les valeurs flex seront ignorées.

Cet exemple est assez simple, mais si on l'agrandit pour inclure une colonne de largeur flexible qui remplit l'espace restant, il est probable flex-shrink flex-shrink et flex-basis les valeurs devraient être converties en propriétés personnalisées. Vous pouvez essayer cela ou prendre un regarder un exemple plus détaillé ici .

Propriétés personnalisées pour la thématisation

Je me suis principalement opposé à l'utilisation de propriétés personnalisées pour les variables dynamiques globales les propriétés du sélecteur : root sont souvent considérées comme nuisibles. Mais chaque règle a une exception, et pour les propriétés personnalisées, c'est un thème.

Une utilisation limitée des propriétés personnalisées globales peut simplifier considérablement la mise en forme.

Généralement, les termes désignent la possibilité pour les utilisateurs de personnaliser l'interface utilisateur. Cela pourrait être quelque chose comme changer les couleurs sur une page de profil. Ou ce pourrait être quelque chose de plus localisé. Par exemple, vous pouvez choisir la couleur d'une note dans l'application Google Keep.


 Google Keep App

Theming consiste généralement à compiler une feuille de style séparée pour remplacer une valeur par défaut avec les préférences utilisateur ou compiler une feuille de style différente pour chaque utilisateur . Les deux peuvent être difficiles et avoir un impact sur les performances.

Avec les propriétés personnalisées, nous n'avons pas besoin de compiler une feuille de style différente; nous avons seulement besoin de mettre à jour la valeur des propriétés en fonction des préférences de l'utilisateur. Comme ils sont des valeurs héritées, si nous le faisons sur l'élément racine, ils peuvent être utilisés n'importe où dans notre application.

Capitaliser les propriétés dynamiques globales

Les propriétés personnalisées sont sensibles à la casse et puisque la plupart des propriétés personnalisées sont locales. En utilisant les propriétés dynamiques globales, il peut être judicieux de les mettre en majuscule.

: root {
  --THEME-COLOR: var (- couleur de l'utilisateur-thème, # d33a2c);
}

La ​​capitalisation des variables signifie souvent des constantes globales. Pour nous, cela signifie que la propriété est définie ailleurs dans l'application et que nous ne devrions probablement pas la modifier localement.

Éviter de définir directement les propriétés dynamiques globales

Les propriétés personnalisées acceptent une valeur de repli. Il peut être utile d'éviter d'écraser directement la valeur d'une propriété personnalisée globale et de séparer les valeurs utilisateur.

L'exemple ci-dessus définit la valeur de - THEME-COLOR à la valeur de - user-theme-color si existe. Si - user-theme-color n'est pas défini, la valeur de # d33a2c sera utilisée. De cette façon, nous n'avons pas besoin de fournir un repli à chaque fois que nous utilisons - THEME-COLOR .

Vous pourriez vous attendre dans l'exemple ci-dessous que le background sera défini au vert. Cependant, la valeur de - user-theme-color n'a pas été définie sur l'élément racine, donc la valeur de - THEME-COLOR n'a pas changé.

: racine {
  --THEME-COLOR: var (- couleur de l'utilisateur-thème, # d33a2c);
}
corps {
  --user-theme-color: vert;
  Arrière-plan: var (- THEME-COLOR);
}

La ​​définition indirecte de propriétés dynamiques globales comme celle-ci les protège contre l'écrasement local et garantit que les paramètres utilisateur sont toujours hérités de l'élément racine. C'est une convention utile pour sauvegarder vos valeurs de thème et éviter l'héritage involontaire.

Si nous voulons exposer des propriétés spécifiques à l'héritage, nous pouvons remplacer le sélecteur : root par un * sélecteur:

: root {
  --THEME-COLOR: var (- couleur de l'utilisateur-thème, # d33a2c);
}
corps {
  --user-theme-color: vert;
  Arrière-plan: var (- THEME-COLOR);
}

Maintenant la valeur de - THEME-COLOR est recalculée pour chaque élément et donc la valeur locale de - user-theme-color peut être utilisée. En d'autres termes, la couleur d'arrière-plan dans cet exemple sera verte.

Vous pouvez voir des exemples plus détaillés de ce modèle dans la section Manipulation de la couleur avec les propriétés personnalisées . JavaScript

Si vous souhaitez définir des propriétés personnalisées à l'aide de JavaScript, il existe une API assez simple qui ressemble à ceci:

 const elm = document.documentElement;
elm.style.setProperty ('- USER-THEME-COLOR', 'tomate');

Ici, je fixe la valeur de - USER-THEME-COLOR sur l'élément de document, ou en d'autres termes, l'élément : root où il sera hérité par tous les éléments.

Ceci n'est pas une nouvelle API; C'est la même méthode JavaScript pour mettre à jour les styles sur un élément. Ce sont des styles en ligne qui auront une plus grande spécificité que les CSS standard.

Cela signifie qu'il est facile d'appliquer des personnalisations locales:

 .note {
  --note-color: #eaeaea;
}
.Remarque {
  arrière-plan: var (- note-color);
}

Ici, je définis une valeur par défaut pour - note-color et la place dans le composant .note . Je garde la déclaration de variable séparée de la déclaration de propriété, même dans cet exemple simple.

 const elm = document.querySelector ('# note-uid');
elm.style.setProperty ('- note-color', 'jaune');

Je cible ensuite une occurrence spécifique d'un élément .note et modifie la valeur de la propriété personnalisée - note-color pour cet élément uniquement. Cela aura maintenant une plus grande spécificité que la valeur par défaut.

Vous pouvez voir comment cela fonctionne avec cet exemple en utilisant React . Ces préférences utilisateur peuvent être enregistrées dans le stockage local ou dans le cas d'une application plus importante peut-être dans une base de données.

Manipuler la couleur avec les propriétés personnalisées

Outre les valeurs hexadécimales et les couleurs nommées, CSS a des fonctions telles que ] rgb () et hsl () . Ceux-ci nous permettent de spécifier les composants individuels d'une couleur telle que la teinte ou la légèreté. Les propriétés personnalisées peuvent être utilisées conjointement avec les fonctions de couleur.

: root {
  --hue: 25;
}
corps {
  arrière-plan: hsl (var (- hue), 80%, 50%);
}

Ceci est utile, mais certaines des fonctionnalités les plus utilisées par les préprocesseurs sont les fonctions de couleur avancées qui permettent de manipuler la couleur en utilisant des fonctions comme éclaircir, assombrir ou désaturer:

 darken ($ base-color, 10%);
éclaircir ($ couleur de base, 10%);
désaturer ($ couleur de base, 20%);

Il serait utile d'avoir certaines de ces fonctionnalités dans les navigateurs. Ils arrivent mais jusqu'à ce que nous ayons des fonctions de modification de couleur natives dans CSS, les propriétés personnalisées pourraient combler une partie de cet espace.

Nous avons vu que les propriétés personnalisées peuvent être utilisées ] rgb () et hsl () mais ils peuvent aussi être utilisés dans calc () . Cela signifie que nous pouvons convertir un nombre réel en pourcentage en le multipliant, par ex. calc (50 * 1%) = 50% .

: racine {
  - Luminosité: 50;
}
corps {
  arrière-plan: hsl (25, 80%, calc (var (- légèreté) * 1%));
}

La ​​raison pour laquelle nous voulons stocker la valeur de luminosité en nombre réel est que nous pouvons la manipuler avec calc avant de la convertir en pourcentage. Par exemple, si je veux assombrir une couleur de 20% je peux multiplier sa luminosité par 0,8 . Nous pouvons rendre cela un peu plus facile à lire en séparant le calcul de luminosité en une propriété personnalisée localement:

: root {
  - Luminosité: 50;
}
corps {
  - luminosité: calc (var (- légèreté * 0.8));
  arrière-plan: hsl (25, 80%, calc (var (- légèreté) * 1%));
}

Nous pourrions même abstraire plus de calculs et créer quelque chose comme fonction de modification de couleur dans CSS en utilisant des propriétés personnalisées . Cet exemple est probablement trop complexe pour la plupart des cas pratiques, mais il démontre toute la puissance des propriétés personnalisées dynamiques

Simplifier la thématisation

L'un des avantages de l'utilisation de propriétés personnalisées est la possibilité de simplifier les thèmes. L'application n'a pas besoin d'être consciente de la façon dont les propriétés personnalisées sont utilisées. Au lieu de cela, nous utilisons JavaScript ou le code côté serveur pour définir la valeur des propriétés personnalisées. La façon dont ces valeurs sont utilisées est déterminée par les feuilles de style.

Cela signifie une fois de plus que nous sommes capables de séparer la logique du design. Si vous avez une équipe de conception technique, les auteurs peuvent mettre à jour des feuilles de style et décider comment appliquer des propriétés personnalisées sans modifier une seule ligne de code JavaScript ou backend.

Les propriétés personnalisées permettent également de déplacer une partie de la complexité. cette complexité peut avoir un impact négatif sur la maintenabilité de votre CSS, alors souvenez-vous de le garder aussi simple que possible.

Utilisation des propriétés personnalisées aujourd'hui

Même si vous prenez en charge IE10 et 11, vous pouvez commencer à utiliser des propriétés personnalisées aujourd'hui. La plupart des exemples de cet article concernent la façon dont nous écrivons et structurons CSS. The benefits are significant in terms of maintainability, however, most of the examples only reduce what could otherwise be done with more complex code.

I use a tool called postcss-css-variables to convert most of the features of custom properties into a static representation of the same code. Other similar tools ignore custom properties inside media queries or complex selectors treating custom properties much like preprocessor variables.

What these tools cannot do is emulate the runtime features of custom properties. This means no dynamic features like theming or changing properties with JavaScript. This might be OK in many situations. Depending on the situation, UI customization might be considered a progressive enhancement and the default theme could be perfectly acceptable for older browsers.

Loading The Correct Stylesheet

There are many ways you can use postCSS. I use a gulp process to compile separate stylesheets for newer and older browsers. A simplified version of my gulp task looks like this:

import gulp from "gulp";
import sass from "gulp-sass";
import postcss from "gulp-postcss";
import rename from "gulp-rename";
import cssvariables from "postcss-css-variables";
import autoprefixer from "autoprefixer";
import cssnano from "cssnano";

gulp.task("css-no-vars", () =>
  gorgée
    .src("./src/css/*.scss")
    .pipe(sass().on("error", sass.logError))
    .pipe(postcss([cssvariables(), cssnano()]))
    .pipe(rename({ extname: ".no-vars.css" }))
    .pipe(gulp.dest("./dist/css"))
);

gulp.task("css", () =>
  gorgée
    .src("./src/css/*.scss")
    .pipe(sass().on("error", sass.logError))
    .pipe(postcss([cssnano()]))
    .pipe(rename({ extname: ".css" }))
    .pipe(gulp.dest("./dist/css"))
);

This results in two CSS files: a regular one with custom properties (styles.css) and one for older browsers (styles.no-vars.css). I want IE10 and 11 to be served styles.no-vars.css and other browsers to get the regular CSS file.

Normally, I’d advocate using feature queries but IE11 doesn’t support feature queries and we’ve used custom properties so extensively that serving a different stylesheet makes sense in this case.

Intelligently serving a different stylesheet and avoiding a flash of unstyled content is not a simple task. If you don’t need the dynamic features of custom properties, you could consider serving all browser styles.no-vars.css and using custom properties simply as a development tool.

If you want to take full advantage of all the dynamic features of custom properties, I suggest using a critical CSS technique. Following these techniques, the main stylesheet is loaded asynchronously while the critical CSS is rendered inline. Your page header might look something like this:

  

We can extend this to load either styles.css or styles.no-vars.css depending on whether the browser supports custom properties. We can detect support like this:

if ( window.CSS && CSS.supports('color', 'var(--test)') ) {
  loadCSS('styles.css');
} autre {
  loadCSS('styles.no-vars.css');
}

Conclusion

If you’ve been struggling to organize CSS efficiently, have difficulty with responsive components, want to implement client-side theming, or just want to start off on the right foot with custom properties, this guide should tell you everything you need to know.

It comes down to understanding the difference between dynamic and static variables in CSS as well as a few simple rules:

  1. Separate logic from design;
  2. If a CSS property changes, consider using a custom property;
  3. Change the value of custom properties, not which custom property is used;
  4. Global variables are usually static.

If you follow these conventions, you will find that working with custom properties is a whole lot easier than you think. This might even change how you approach CSS in general.

Further Reading

Smashing Editorial(ra, yk, il)




Source link