Fermer

juillet 1, 2019

Propriétés personnalisées CSS dans The Cascade


Dans cet article, Miriam approfondit son analyse de la spécification ' Propriétés personnalisées CSS pour les variables en cascade ' en demandant: “Pourquoi sont-elles appelées propriétés personnalisées, comment fonctionnent-elles dans la cascade? pouvons-nous faire avec eux? »En dépassant la métaphore« variable », les propriétés personnalisées peuvent fournir de nouveaux moyens d'équilibrer le contexte et l'isolation dans les modèles et les composants CSS.

Le mois dernier, j'ai eu une conversation sur sur Twitter sur la différence entre les styles «étendus» (générés dans un processus de construction) et les styles «imbriqués» natifs de CSS. J'ai demandé pourquoi, de façon anecdotique, les développeurs évitaient la spécificité des sélecteurs d'identifiants, tout en adoptant les «styles étendus» générés par JavaScript? Keith Grant a suggéré que la différence réside dans l’équilibre entre la cascade * et l’héritage, c’est-à-dire en privilégiant la proximité par rapport à la spécificité. Jetons un coup d'œil.

The Cascade

La cascade CSS repose sur trois facteurs:

  1. Importance définie par le drapeau important et son style. origine (utilisateur> auteur> navigateur)
  2. Spécificité des sélecteurs utilisés (inline> ID> classe> élément)
  3. Ordre de la source du code lui-même (le dernier a priorité)

Proximité

n'est mentionnée nulle part – la relation d'arborescence DOM entre des parties d'un sélecteur. Les paragraphes ci-dessous seront tous deux en rouge, même si #inner p décrit une relation plus étroite que #outer p pour le deuxième paragraphe:

Voir le stylo [Cascade: Specificity vs Proximity] (https: //codepen.io/smashingmag/pen/OexweJ/) de Miriam Suzanne .

Voir le stylo Cascade: spécificité vs proximité de Miriam Suzanne .

Ce texte est rouge

Ce texte est également rouge!

 #inner p {
  la couleur verte;
}

#outer p {
  La couleur rouge;
}

Les deux sélecteurs ont la même spécificité, ils décrivent tous deux le même élément p et aucun des deux sélecteurs n'est marqué comme ! Important – le résultat est donc basé uniquement sur l'ordre des sources.

Styles BEM et Scoped

Des conventions de dénomination telles que BEM (“Block__Element — Modifier”) sont utilisées pour garantir que chaque paragraphe est “délimité” par un seul parent, évitant ainsi totalement la cascade. Les paragraphes «éléments» ont des classes uniques propres à leur contexte de «bloc»:

Voir le stylo [BEM Selectors & Proximity] (https://codepen.io/smashingmag/pen/qzPyeM/) de de Miriam Suzanne .

Voir le stylo BEM Selectors & Proximity de Miriam Suzanne .

Ce texte est en rouge

Ce texte est en vert!

 .inner__p {
  la couleur verte;
}

.outer__p {
  La couleur rouge;
}

Ces sélecteurs ont toujours la même importance relative, la même spécificité et le même ordre source – mais les résultats sont différents. Des outils CSS «scopés» ou «modulaires» automatisent ce processus en réécrivant notre code CSS, basé sur le code HTML. Dans le code ci-dessous, chaque paragraphe est associé à son parent direct:

Voir le stylo [Scoped Style Proximity] (https://codepen.io/smashingmag/pen/NZaLWN/) de de Miriam Suzanne . [19659010] Voir le stylo Proximité du style limité de Miriam Suzanne .

Ce texte est en rouge

Ce texte est en vert!

 p [inner-scope]
  la couleur verte
}

p [outer-scope] {
  La couleur rouge;
}

Héritage

La proximité ne fait pas partie de la cascade, mais du CSS. C’est là que l’héritage devient important. Si nous supprimons le p de nos sélecteurs, chaque paragraphe héritera d'une couleur de son ancêtre le plus proche:

Voir le stylo [Inheritance: Specificity vs Proximity] (https://codepen.io/smashingmag/pen/mZBGyN/ ) de Miriam Suzanne .

Voir le stylo Héritage: spécificité vs proximité de Miriam Suzanne .
 #inner {
  la couleur verte;
}

#outer {
  La couleur rouge;
}

Depuis #inner et #outer décrivent différents éléments, nos sections div et étant respectives, les deux propriétés de couleur sont appliquées sans conflit. . L'élément imbriqué p n'a pas de couleur spécifiée. Les résultats sont donc déterminés par héritage (la couleur du parent direct) plutôt que par cascade . La proximité a la priorité et la valeur #inner remplace la #outer .

Mais il y a un problème: pour utiliser l'héritage, nous appelons tout dans notre section et div . Nous voulons cibler spécifiquement la couleur du paragraphe.

(Re) Introduction aux propriétés personnalisées

Les propriétés personnalisées fournissent une nouvelle solution native pour le navigateur; ils héritent comme n'importe quel autre bien, mais ils ne doivent pas être utilisés là où ils sont définis . En utilisant du CSS simple, sans conventions de nommage ni outils de construction, nous pouvons créer un style à la fois ciblé et contextuel, la proximité prévalant sur la cascade:

Voir le stylo [Custom Props: Specificity vs Proximity] (https://codepen.io/ smashingmag / pen / gNGdaO /) de Miriam Suzanne .

Voir le stylo Les accessoires personnalisés: Spécificité par rapport à la proximité de Miriam Suzanne .
 p {1965}
  couleur: var (- paragraphe);
}

#inner {
  - paragraphe: vert;
}

#outer {
  - paragraphe: rouge;
}

La propriété - paragraphe hérite de la même propriété que la propriété color mais nous contrôlons maintenant exactement comment et où cette valeur est appliquée. La propriété - paragraph agit comme un paramètre qui peut être transmis à la composante p soit par sélection directe (règles de spécificité), soit par contexte (règles de proximité). [19659034] Je pense que cela révèle un potentiel pour les propriétés personnalisées que nous associons souvent aux fonctions, mixins ou composants.

Paramètres et fonctions personnalisés

Les fonctions, mixins et composants sont tous basés sur la même idée: code réutilisable. , qui peut être exécuté avec divers paramètres d’entrée pour obtenir des résultats cohérents mais configurables. La distinction est dans ce qu'ils font avec les résultats. Nous commencerons par une variable en dégradé de bandes, puis nous pourrons l'étendre à d'autres formes:

 html {
  --stripes: linéaire-gradient (
    à droite,
    bleu poudre 20%, rose 20% 40%, blanc 40% 60%, rose 60% 80%, bleu poudre 80%
  )
}

Cette variable est définie sur l'élément root html (peut également utiliser : root mais cela ajoute une spécificité inutile), de sorte que notre variable rayée sera disponible partout dans le document. Nous pouvons l'appliquer partout où les gradients sont pris en charge:

Voir le stylo [Custom Props: Variable] (https://codepen.io/smashingmag/pen/NZwrrm/) de Miriam Suzanne .

Voir le stylo Accessoires sur mesure: Variable de Miriam Suzanne .
 body {
  image d’arrière-plan: var (- rayures);
}

Ajout de paramètres

Les fonctions sont utilisées comme des variables, mais définissent des paramètres pour modifier la sortie. Nous pouvons mettre à jour notre variable - stripes pour qu'elle ressemble davantage à une fonction en définissant certaines variables analogues à des paramètres. Je commencerai par remplacer à droite par var (- stripes-angle) pour créer un paramètre de changement d’angle:

 html {
  --stripes: linéaire-gradient (
    var (- rayures-angle),
    bleu poudre 20%, rose 20% 40%, blanc 40% 60%, rose 60% 80%, bleu poudre 80%
  )
}

Nous pourrions créer d'autres paramètres, en fonction de l'objectif visé par la fonction. Devrions-nous permettre aux utilisateurs de choisir leurs propres couleurs de bandes? Si tel est le cas, notre fonction accepte-t-elle 5 paramètres de couleur différents ou seulement 3 qui iront de l’extérieur comme nous le faisons maintenant? Voulons-nous aussi créer des paramètres pour les arrêts de couleur? Chaque paramètre ajouté apporte davantage de personnalisation au détriment de la simplicité et de la cohérence.

Il n’existe pas de bonne réponse universelle à cet équilibre: certaines fonctions doivent être plus souples et d’autres plus avisées. Les abstractions existent pour assurer la cohérence et la lisibilité de votre code, prenez donc du recul et demandez quels sont vos objectifs. Qu'est-ce qui doit vraiment être personnalisable et où la cohérence doit-elle être appliquée? Dans certains cas, il peut être plus utile d’avoir deux fonctions liées à une opinion, plutôt qu’une fonction entièrement personnalisable.

Pour utiliser la fonction ci-dessus, nous devons passer une valeur pour - stripes-angle et appliquez la sortie à une propriété de sortie CSS, comme background-image :

 / * en plus du code ci-dessus… * /
html {
  --stripes-angle: 75deg;
  image d’arrière-plan: var (- rayures);
}

Voir le stylo [Custom Props: Function] (https://codepen.io/smashingmag/pen/BgwOjj/) de Miriam Suzanne .

Voir le stylo Custom Props: Function par Miriam Suzanne .

Inherited Versus Universal

J'ai défini la fonction - stripes de l'élément html hors de ses habitudes. Les propriétés personnalisées héritent, et je veux que ma fonction soit disponible partout. Il est donc logique de la placer sur l'élément racine. Cela fonctionne bien pour hériter de variables telles que - couleur de la marque: bleu de sorte que nous pourrions également nous attendre à ce que cela fonctionne également pour notre "fonction". Mais si nous essayons à nouveau d'utiliser cette fonction sur un sélecteur imbriqué, cela ne fonctionnera pas:

Voir le stylo [Custom Props: Function Inheritance Fail] (https://codepen.io/smashingmag/pen/RzjRrM/) de Miriam Suzanne .

Voir le stylo Accessoires personnalisés: échec de la fonction héritage de Miriam Suzanne .
 div {
  --stripes-angle: 90deg;
  image d’arrière-plan: var (- rayures);
}

Le nouveau - angle de bande est totalement ignoré. Il s'avère que nous ne pouvons pas compter sur l'héritage pour les fonctions qui doivent être recalculées. C’est parce que chaque valeur de propriété est calculée une fois par élément (dans notre cas, l’élément racine html ), puis la valeur calculée est héritée de . En définissant notre fonction à la racine du document, nous ne mettons pas toute la fonction à la disposition des descendants, mais uniquement du résultat calculé de notre fonction.

Cela a du sens si vous l'encadrez en termes de cascade - stripes paramètre -angle . Comme toute propriété CSS héritée, elle est disponible pour les descendants mais pas pour les ancêtres. La valeur que nous avons définie sur un div imbriquée n'est pas disponible pour une fonction que nous avons définie sur l'ancêtre de la racine html . Afin de créer une fonction universellement disponible qui recalculera sur n'importe quel élément, nous devons la définir pour chaque élément:

Voir le stylo [Custom Props: Universal Function] (https://codepen.io/smashingmag/pen/agLaNj /) de Miriam Suzanne .

Voir le stylo Les accessoires sur mesure: fonction universelle de Miriam Suzanne .
 * {{
  --stripes: linéaire-gradient (
    var (- rayures-angle),
    bleu poudre 20%, rose 20% 40%, blanc 40% 60%, rose 60% 80%, bleu poudre 80%
  )
}

Le sélecteur universel rend notre fonction disponible partout, mais nous pouvons le définir plus précisément si nous le souhaitons. L'important est qu'il ne puisse recalculer que là où il est explicitement défini. Voici quelques alternatives:

 / * rendre la fonction disponible pour les éléments ayant un sélecteur donné * /
.stripes {--stripes: / * etc… * /; }

/ * rend la fonction disponible pour les éléments imbriqués dans un sélecteur donné * /
.stripes * {--stripes: / * etc… * /; }

/ * met la fonction à la disposition des frères et soeurs suivant un sélecteur donné * /
.stripes ~ * {--stripes: / * etc… * /; }

Voir le stylo [Custom Props: Scoped Function] (https://codepen.io/smashingmag/pen/JQMvGM/) de Miriam Suzanne .

Voir le stylo Custom Props: Scoped Function de Miriam Suzanne .

Cette option peut être étendue à toute logique de sélecteur qui ne repose pas sur l'héritage.

Paramètres libres et valeurs de repli

Dans notre exemple ci-dessus, var (- stripes-angle) n'a pas de valeur ni de repli. Contrairement aux variables Sass ou JS qui doivent être définies ou instanciées avant d'être appelées, les propriétés personnalisées CSS peuvent être appelées sans jamais être définies. Cela crée une variable «libre», similaire à un paramètre de fonction pouvant être hérité du contexte.

Nous pouvons éventuellement définir la variable sur html ou : root (ou autre ancêtre) pour définir une valeur héritée, mais nous devons d’abord considérer le repli si aucune valeur n’est définie. Il existe plusieurs options, en fonction du comportement souhaité (19659076). Pour les paramètres "obligatoires", nous ne souhaitons pas une solution de secours. En l'état, la fonction ne fera rien jusqu'à ce que soit définie - stripes-angle .

  • Pour les paramètres «facultatifs», nous pouvons fournir une valeur de repli dans var () . une fonction. Après le nom de la variable, nous ajoutons une virgule, suivie de la valeur par défaut:
  •  var (- stripes-angle, 90deg)
    

    Chaque fonction var () ne peut avoir qu'un seul repli – de sorte que toute virgule supplémentaire fera partie de cette valeur. Cela permet de fournir des valeurs complexes par défaut avec des virgules internes:

     html {
      / * Calculé: Hevetica, Ariel, sans-serif * /
      font-family: var (- sans-family, Hevetica, Ariel, sans-serif);
    
      / * Calculé: 0 -1px 0 blanc, 0 1px 0 noir * /
      test-shadow: var (- shadow, 0 -1px 0 blanc, 0 1px 0 noir);
    }
    

    Nous pouvons également utiliser des variables imbriquées pour créer nos propres règles de cascade, en donnant différentes priorités aux différentes valeurs:

     var (- stripes-angle, var (- global-default-angle, 90deg))
    
    1. Essayons d’abord notre paramètre explicite ( - angle de bande );
    2. Reconstitution d’un «paramètre par défaut» global ( - angle d’utilisateur par défaut ) si il est disponible;
    3. Enfin, nous nous associons à notre "paramètre d'usine" (90deg ).

    Voir le stylo [Custom Props: Fallback Values] (https://codepen.io/smashingmag/pen/jjGVVm/) par Miriam Suzanne .

    Voir le stylo Les accessoires personnalisés: valeurs de repli de Miriam Suzanne .

    En définissant des valeurs de repli dans var ( ) plutôt que de définir explicitement la propriété personnalisée, nous nous assurons qu'il n'y a pas de spécificité ni de restrictions en cascade sur le paramètre. Tous les paramètres * - angle peuvent «être hérités» de n'importe quel contexte.

    Replis du navigateur par rapport aux replis variables

    Lorsque nous utilisons des variables, nous devons conserver deux chemins de repli à l'esprit:

    1. Quelle valeur doit être utilisée par les navigateurs sans prise en charge de variables?
    2. Quelle valeur doit être utilisée par les navigateurs qui prennent en charge les variables, lorsqu'une variable est manquante ou invalide?
     p {0}
      Couleur bleue;
      couleur: var (- paragraphe);
    }
    

    Tandis que les anciens navigateurs ignorent la propriété de déclaration de variable et se replient sur blue – les navigateurs modernes lisent les deux et utilisent le dernier. Notre var (- paragraph) peut ne pas être défini, mais il est valide et remplacera la propriété précédente. Par conséquent, les navigateurs avec prise en charge variable se replieront sur la valeur héritée ou initiale, comme si vous utilisiez le unset mot-clé.

    Cela peut sembler déroutant au début, mais il y a de bonnes raisons à cela. La première est technique: les moteurs de navigateur gèrent la syntaxe non valide ou inconnue à "l'heure de l'analyse" (ce qui se produit en premier), mais les variables ne sont pas résolues avant "l'heure de la valeur calculée" (ce qui se produit plus tard).

    1. Au moment de l'analyse, les déclarations avec une syntaxe non valide sont complètement ignorées, ce qui revient aux déclarations antérieures. C'est le chemin que suivront les anciens navigateurs. Les navigateurs modernes supportent la syntaxe de variable, la déclaration précédente est donc ignorée.
    2. Au moment de la calcul de la valeur, la variable est compilée comme non valide, mais il est trop tard – la déclaration précédente a déjà été ignorée. Selon la spécification, les valeurs de variable invalide sont traitées de la même manière que non défini :

    Voir le stylo [Custom Props: Invalid/Unsupported vs Undefined] (https://codepen.io/smashingmag/ pen / VJMGbJ /) de Miriam Suzanne .

    Voir le stylo Accessoires personnalisés: Invalid / Unsupported vs Undefined de Miriam Suzanne .
     html {
      La couleur rouge;
      
      / * ignoré en tant que * syntaxe non valide * par tous les navigateurs * /
      / * - anciens navigateurs: rouge * /
      / * - nouveaux navigateurs: rouge * /
      couleur: pas une couleur valide;
      color: var (nom de variable non valide);
      
      / * ignoré en tant que * syntaxe non valide * par les navigateurs sans support var * /
      / * syntaxe valide, mais non valide * valeurs * dans les navigateurs modernes * /
      / * - anciens navigateurs: rouge * /
      / * - nouveaux navigateurs: unset (black) * /
      --invalid-value: pas une valeur de couleur valide;
      couleur: var (- variable-non définie);
      couleur: var (- valeur invalide);
    }
    

    Cela nous convient également aux auteurs, car cela nous permet de jouer avec des solutions de repli plus complexes pour les navigateurs prenant en charge des variables et de fournir des solutions de repli simples aux navigateurs plus anciens. Mieux encore, cela nous permet d'utiliser l'état null / undefined pour définir les paramètres requis. Cela devient particulièrement important si vous voulez transformer une fonction en un mixin ou un composant.

    Propriété personnalisée «Mixins»

    Dans Sass, les fonctions renvoient des valeurs brutes, tandis que mixins renvoie généralement la sortie CSS réelle avec des paires propriété-valeur. Lorsque nous définissons une propriété universelle - stripes sans l'appliquer à une sortie visuelle, le résultat est semblable à une fonction. Nous pouvons faire en sorte que cela se comporte davantage comme un mixin, en définissant également la sortie de manière universelle:

     * {{
      --stripes: linéaire-gradient (
        var (- rayures-angle),
        bleu poudre 20%, rose 20% 40%, blanc 40% 60%, rose 60% 80%, bleu poudre 80%
      )
      image d’arrière-plan: var (- rayures);
    }
    

    Tant que - stripes-angle reste invalide ou indéfini, le mixin ne parvient pas à être compilé et aucun image de fond ne sera appliqué. Si nous définissons un angle valide sur n'importe quel élément, la fonction calculera et nous donnera un arrière-plan:

     div {
      --stripes-angle: 30deg; / * génère le fond * /
    }
    

    Malheureusement, cette valeur-paramètre héritera de . La définition actuelle crée donc un arrière-plan sur la div et tous les descendants . Pour résoudre ce problème, nous devons nous assurer que la valeur - Stripes-angle n’hérite pas, en la reposant à la valeur initiale (ou toute valeur non valide) sur chaque élément. Nous pouvons le faire sur le même sélecteur universel:

    Voir le stylo [Custom Props: Mixin] (https://codepen.io/smashingmag/pen/ZdXMJx/) de Miriam Suzanne .

    Voir le Stylo Accessoires sur mesure: Mixin de Miriam Suzanne .
     * {
      --stripes-angle: initial;
      --stripes: / * etc… * /;
      image d’arrière-plan: var (- rayures);
    }
    

    Styles en ligne sûrs

    Dans certains cas, il est nécessaire que le paramètre soit défini de manière dynamique à partir de l'extérieur de CSS – en fonction des données d'un serveur principal ou d'une infrastructure frontale. Avec les propriétés personnalisées, nous pouvons définir en toute sécurité des variables dans notre code HTML sans vous soucier des problèmes de spécificité habituels:

    Voir le stylo [Custom Props: Mixin + Inline Style] (https://codepen.io/smashingmag/pen/qzPMPv/) de Miriam Suzanne .

    Voir le stylo Accessoires sur mesure: Mixin + Inline Style de Miriam Suzanne .
     
    ...

    Les styles en ligne ont une grande spécificité et sont très difficiles à remplacer – mais avec les propriétés personnalisées, nous avons une autre option: l'ignorer. Si nous fixons la div à background-image: none (par exemple), cette variable en ligne n'aura aucun impact. Pour aller encore plus loin, nous pouvons créer une variable intermédiaire:

     * {--stripes-angle: var (- stripes-angle-dynamic, initial); }
    

    Nous avons maintenant la possibilité de définir - stripes-angle-dynamic dans le code HTML, ou de l'ignorer, et de définir - stripes-angle directement dans notre feuille de style. 19659122] Voir le stylo [Custom Props: Mixin + Inline / Override] (https://codepen.io/smashingmag/pen/ZdXMao/) de Miriam Suzanne .

    Voir le stylo Custom Props: Mixin + Inline / Remplacer par Miriam Suzanne .

    Valeurs prédéfinies

    Pour les valeurs plus complexes ou les modèles courants que nous souhaitons réutiliser, nous pouvons également fournir quelques variables prédéfinies parmi lesquelles choisir: [19659055] * {
      – bascule: 6deg;
      -til-up: -6deg;
    }

    Et utilisez ces préconfigurations plutôt que de définir directement la valeur:

     
    ...

    Voir le stylo [Custom Props: Mixin + Presets] (https://codepen.io/smashingmag/pen/LKemZm/) par Miriam Suzanne .

    Voir le stylo Accessoires personnalisés: Mixin + Presets de Miriam Suzanne .

    Cette fonction est idéale pour créer des graphiques et des graphiques basés sur données dynamiques, ou même établissant un agenda .

    Voir le stylo [Bar chart in CSS grid + variables] (https://codepen.io/smashingmag/pen/wLrEyg/) de Miriam Suzanne .

    Voir le stylo Diagramme à barres de la grille CSS + variables de Miriam Suzanne .

    Composantes contextuelles

    Nous pouvons également recadrer notre "mixin" comme un «composant» en l'appliquant à un sélecteur explicite et en rendant les paramètres facultatifs. Plutôt que de compter sur la présence ou l'absence de - rayures-angle pour basculer notre sortie, nous pouvons nous fier à la présence ou à l'absence d'un sélecteur de composant. Cela nous permet de définir des valeurs de repli en toute sécurité:

    Voir le stylo [Custom Props: Component] (https://codepen.io/smashingmag/pen/QXqVmM/) de Miriam Suzanne .

    Voir le stylo Custom Props: Component de Miriam Suzanne .
     [data-stripes] {
      --stripes: linéaire-gradient (
        var (- stripes-angle, à droite),
        bleu poudre 20%, rose 20% 40%, blanc 40% 60%, rose 60% 80%, bleu poudre 80%
      )
      image d’arrière-plan: var (- rayures);
    }
    

    En plaçant le repli dans la fonction var () nous pouvons laisser - stripes-angle indéfini et «libre» d'hériter d'une valeur provenant de l'extérieur du composant. C'est un excellent moyen d'exposer certains aspects d'un style de composant à une entrée contextuelle. Même les styles «étendus» générés par un framework JS (ou à l'intérieur du shadow-DOM, comme les icônes SVG) peuvent utiliser cette approche pour exposer des paramètres spécifiques d'influence extérieure.

    Isolated Components

    Si nous ne le souhaitons pas exposer le paramètre pour l'héritage, nous pouvons définir la variable avec une valeur par défaut:

     [data-stripes] {
      --stripes-angle: à droite;
      --stripes: linéaire-gradient (
        var (- stripes-angle, à droite),
        bleu poudre 20%, rose 20% 40%, blanc 40% 60%, rose 60% 80%, bleu poudre 80%
      )
      image d’arrière-plan: var (- rayures);
    }
    

    Ces composants fonctionneraient également avec une classe ou tout autre sélecteur valide, mais j'ai choisi l'attribut data- pour créer un espace de noms pour tous les modificateurs souhaités:

     [data-stripes='vertical'] {- rayures-angle: vers le bas; }
    [data-stripes='horizontal'] {--stripes-angle: à droite; }
    [data-stripes='corners'] {--stripes-angle: en bas à droite; }
    

    Voir le stylo [Custom Props: Isolated Components] (https://codepen.io/smashingmag/pen/agLaGX/) de Miriam Suzanne .

    Voir le stylo Accessoires sur mesure: Composants isolés de Miriam Suzanne .

    Sélecteurs et paramètres

    Je souhaiterais souvent pouvoir utiliser des attributs de données pour définir une variable – une fonctionnalité prise en charge par le CSS3 attr () spécification mais non encore implémentée dans les navigateurs (voir l'onglet Ressources pour les problèmes liés sur chaque navigateur). Cela nous permettrait d'associer plus étroitement un sélecteur à un paramètre particulier:

     
    ...
    / * Partie de la spécification CSS3, mais pas encore supportée * / / * attr () * / [data-stripes] {   --stripes-angle: attr (angle des bandes de données, à droite); }

    En attendant, vous pouvez obtenir quelque chose de similaire en utilisant l'attribut de style :

    Voir le stylo [Custom Props: Style Selectors] (https://codepen.io / smashingmag / pen / PrJdBG /) de Miriam Suzanne .

    Voir le stylo Les accessoires sur mesure: Style Selectors de Miriam Suzanne .
     
    ] ... ...
    / * Le sélecteur d'attribut `* =` fera correspondre une chaîne n'importe où dans l'attribut * / [style*='--stripes-angle'] {   / * Définit uniquement la fonction où nous voulons l'appeler * /   --stripes: linéaire-gradient (…); }

    Cette approche est particulièrement utile lorsque l'on souhaite inclure d'autres propriétés en plus du paramètre en cours de définition. Par exemple, la définition d’une zone de grille peut également ajouter un remplissage et un arrière-plan:

     [style*='--grid-area'] {
      couleur de fond: blanc;
      zone de grille: var (- zone de grille, auto / 1 / auto / -1);
      rembourrage: 1em;
    }
    

    Conclusion

    Lorsque nous commençons à rassembler tous ces éléments, il devient évident que les propriétés personnalisées vont bien au-delà des cas d’utilisation de variables courants que nous connaissons bien. Nous ne sommes pas seulement capables de stocker des valeurs et de les définir dans la cascade – nous pouvons également les utiliser pour manipuler la cascade de nouvelles façons et créer des composants plus intelligents directement dans CSS.

    Cela nous oblige à repenser de nombreuses personnes. des outils sur lesquels nous nous sommes appuyés dans le passé – des conventions de dénomination telles que SMACSS et BEM, aux styles «étendus» et CSS-in-JS. Bon nombre de ces outils permettent de contourner les spécificités ou de gérer les styles dynamiques dans une autre langue – cas d'utilisation que nous pouvons désormais traiter directement avec des propriétés personnalisées. Les styles dynamiques que nous avons souvent calculés dans JS peuvent désormais être gérés en transmettant des données brutes au CSS.

    Ces modifications peuvent être considérées dans un premier temps comme une “complexité supplémentaire”, car nous ne sommes pas habitués à voir la logique à l'intérieur. CSS. Et, comme pour tout code, la sur-ingénierie peut être un réel danger. Mais je dirais que dans de nombreux cas, nous pouvons utiliser ce pouvoir non pas pour ajouter de la complexité mais pour déplacer la complexité hors des outils et des conventions de tiers, pour revenir dans le langage de base de conception de sites Web, et (plus important encore) dans le navigateur. Si nos styles nécessitent des calculs, ceux-ci doivent être intégrés à notre CSS.

    Toutes ces idées peuvent être poussées beaucoup plus loin. Les propriétés personnalisées commencent à peine à être adoptées plus largement, et nous avons seulement commencé à gratter la surface de ce qui est possible. Je suis impatient de voir où cela se passe et ce que les autres proposent. Amusez-vous!

    Lectures suggérées

     Editorial Smashing (dm, il)






    Source link