web-dev-qa-db-fra.com

Variables CSS avec secours pour les anciens navigateurs

TL; DR: Comment pouvez-vous utiliser SCSS pour avoir des variables CSS avec un repli pour les navigateurs plus anciens.

J'essaie de comprendre cela article . À mon avis, vous devez déjà être un utilisateur avancé de SASS pour le comprendre, ce que je ne suis pas. Pour aggraver les choses, c'est le seul article que j'ai trouvé sur le sujet.

Voici ce que j'essaie de réaliser:

Mon scss devrait être dans le sens de:

body {
  @include v(background-color, primary)
}

alors le traitement [~ # ~] css [~ # ~] doit être

body{
   background: yellow; /* Yellow being defined above as the primary color */
   background: var(--color-primary);
}

En jouant un peu, je peux déjà obtenir la valeur de la variable CSS comme ceci:

$colors: (
  primary: yellow,
);

:root {
  @each $name, $color in $colors {
    --color-#{$name}: $color;
  }
}

@mixin background-color($color_) {
  background: var(--color-#{$color_});
}

Pour l'utiliser:

body{
  @include background-color(primary);
}

Ce qui se traduira par ceci:

body {
    background: var(--color-primary);
    /* But the fallback is missing :(, I tried  things with the map-get but it's really eluding me... */
}
11
Ced

Si vous utilisez Sass, vous pouvez automatiser les remplacements via un mixin Sass. Créez une carte de vos noms de variables CSS et de leurs valeurs, puis vous pouvez rechercher ces valeurs dans un mixin qui génère le style de secours et celui préféré

$vars: (
  primary: yellow,
);

:root {
  --primary: map-get($vars, primary);
}

@mixin var($property, $varName) {
  #{$property}: map-get($vars, $varName);
  #{$property}: var(--#{$varName});
}

Le mixin ci-dessus est utilisé comme suit:

body {
  @include var(background-color, primary);
}

et génère le CSS suivant:

:root {
  --primary: yellow;
}

body {
  background-color: yellow;
  background-color: var(--primary);
}

Et voilà :)

14
rdhainaut

Mise à jour: propriétés personnalisées Postcss peut faire un repli et est beaucoup plus facile que le code ci-dessous

étape 1: déclarer les variables scss

Donc, tout d'abord, nous voulons mettre quelques variables dans un $map, J'irai avec des variables de couleur:

$colors: (
  primary: #FFBB00,
  secondary: #0969A2
);

étape 2: automatiser la génération var css 4

// ripped CSS4 vars out of color map
:root {
  // each item in color map
  @each $key, $value in $colors {
    --colors-#{$key}: $value;
  }
}

Ce qui se passe en root c'est: pour chaque clé et valeur dans les couleurs map, on imprime ce qui suit:

--colors-#{$key}: $value;

Ce qui correspond aux déclarations de variables css. Je crois que le peu bizarre avec #{} autour de la clé est de ne pas avoir d'espaces autour de la valeur. Le résultat est donc:

--colors-primary: #FFBB00,
--colors-secondary: #0969A2

Notez que le préfixe (--colors-) est le même nom que la carte de couleurs scss au-dessus. Le pourquoi deviendra clair à la dernière étape.


étape 3: beaucoup de cartes!

$props: (
  background-color: $colors
);

$map-maps: (
  background-color: colors
);

Ici, nous ajoutons la carte $props qui mappe une propriété css à la carte contenant les valeurs. background-color tiendra la couleur, donc la bonne carte est $colors.

map-maps est une copie d'accessoires où au lieu de la carte, nous avons le nom de ladite carte. (ceci est relatif à la note de l'étape 2).

Étape 4: faisons-le fonctionner!

@mixin v($prop, $var) {
  // get the map from map name
  $map: map-get($props, $prop);
  // fallback value, grab the variable's value from the map
  $var-fall: map-get($map, $var);
  // our css4 variable output
  $var-output: var(--#{$map}-#{$var});    
  #{$prop}: $var-fall;
  // css4 variable output
  #{$prop}: $var-output;
}

body{
  @include v(background-color, primary);
}

J'ai simplifié un peu le code de l'article, cela fonctionne toujours, pour cet exemple au moins, le code de l'article prend plus en compte.

Quoi qu'il en soit, voici ce qui se passe.

Tout d'abord, nous appelons le mixin avec:

  @include v(background-color, primary);

Puis en entrant,

 $map: map-get($props, $prop); // map-get($props, background-color)

nous avons une variable appelée $map à laquelle nous attribuons la valeur qui est à l'intérieur du $props carte à la clé background-color qui se trouve être le $colors carte. C'est un peu un labyrinthe mais ce n'est pas si compliqué une fois que vous l'avez résolu.

Alors pour le repli:

 $var-fall: map-get($map, $var);

Cela obtient simplement la valeur de la carte que nous venons d'obtenir (qui est $colors) au $var clé (qui se trouve être principale). Ainsi, le résultat est #FFBB00.

Pour le css var

  $map-name: map-get($map-maps, $prop);
  $var-output: var(--#{$map-name}-#{$var});

nous recréons ce que nous avons fait pour générer le var dans le @each boucle


Le code entier serait:

$colors: (
  primary: #FFBB00,
  secondary: #0969A2
);

// ripped CSS4 vars out of color map
:root {
  // each item in color map
  @each $name, $color in $colors {
    --colors-#{$name}: $color;
  }
}



$props: (
  background-color: $colors,
  color:            $colors
);

$map-maps: (
  background-color: colors
);



@mixin v($prop, $var) {
  // get the map from map name
  $map: map-get($props, $prop);
  // fallback value, grab the variable's value from the map
  $var-fall: map-get($map, $var);
  // our css4 variable output

  $map-name: map-get($map-maps, $prop);
  $var-output: var(--#{$map-name}-#{$var});

  #{$prop}: $var-fall;
  // css4 variable output
  #{$prop}: $var-output;
}

body{
  @include v(background-color, primary);
}

Maintenant, c'est une simplification de ce qui est fait dans l'article. Vous devriez le vérifier pour avoir un code un peu plus robuste.

11
Ced

Je suppose que vous connaissez la raison pour laquelle cela n'a pas montré le repli. Mais comme c'est une réponse, je vais expliquer les raisons

Le bloc de mixage actuel n'a qu'une seule propriété d'arrière-plan, ce qui fait que le compilateur sass ne génère qu'une seule propriété. Je ne pense pas que Sass puisse identifier si 'var' est supporté dans le navigateur ou non. Donc, nous devons spécifier explicitement si nous avons besoin du repli.

Puisque vous avez déjà la carte, tout ce dont vous avez besoin est d'obtenir la valeur en donnant la clé "primaire"

 @mixin background-color($color_) {
      background: var(--color-#{$color_});  
      background: map-get($colors, primary);
    }

Cela ajoutera toujours le fond: le jaune à la classe de corps. Alternativement, si vous souhaitez contrôler l'ajout de secours en fonction de la condition. Vous pouvez faire comme ça

@mixin background-color($color_, $showFall) {
  background: var(--color-#{$color_});  
  @if $showFall {
    background: map-get($colors, primary);
  }
}

et appeler comme ça

body{
  @include background-color(primary, true);
}

Stylo à code pour le même https://codepen.io/srajagop/pen/xdovON

Remarque: j'écris la réponse en supposant que vous ne voulez que la couleur d'arrière-plan et pas toutes les autres propriétés comme mentionné dans cet article. Pour cela, vous devez créer une structure de données appropriée

1
karthick