web-dev-qa-db-fra.com

Est-il possible d'utiliser des variables CSS dans le tableau Twitter-bootstrap 4 $ theme-colors?

Dans bootstrap 4, vous pouvez définir et/ou remplacer les couleurs par défaut en utilisant le tableau suivant: ( comme documenté ici )

$theme-colors: (
    "primary": #001122, /*override*/
    "color-1": red, /*new color*/
    "color-2": black, /*new color*/
    "color-3": white /*new color*/
);

Je veux créer des couleurs de thème personnalisées pour différents utilisateurs. Les utilisateurs peuvent choisir différentes palettes de couleurs que j'ai définies en fonction de la classe du corps.

J'ai créé un nouveau fichier pour créer mes propres styles, en définissant les couleurs de mon thème dans des variables CSS dans la balise body:

body {
  &.color-pallette-red {
    --theme-color-1: red;
    --theme-color-2: black;
    --theme-color-3: white;

    color: var(--theme-color-1); /*red*/
  }

  &.color-pallette-yellow {
    --theme-color-1: yellow;
    --theme-color-2: black;
    --theme-color-3: white;

    color: var(--theme-color-1); /*yellow*/
  }
}

Mais de cette façon, les couleurs bootstrap ne sont bien sûr pas écrasées ...

J'ai essayé de coller mes variables CSS dans le tableau bootstrap mentionné précédemment, pour m'assurer que bootstrap utilisait mes couleurs:

$theme-colors: (
    "color-1": var(--theme-color-1),
    "color-2": var(--theme-color-2),
    "color-3": var(--theme-color-3)
);

Mais cela renvoie Error: $color2: var(--theme-color-1) is not a color. @return mix($color-base, $color, $level * $theme-color-interval); après avoir exécuté le script de compilation. Donc, bootstrap/compiler n'a pas reconnu mes variables CSS comme une couleur ...

Voici ce que je veux résumer: Changer les couleurs bootstrap en fonction de la classe corporelle. Quelqu'un sait-il comment y parvenir?

15
djl

Vous ne pouvez pas définir les variables CSS directement dans les cartes, car cette variable ne serait pas compilée à l'époque car SASS est un préprocesseur, en plus bootstrap se retourne et convertit ces KVP de thème en variables :root de toute façon, donc vous faites essentiellement la même chose deux fois. Une façon de contourner cela est que vous pouvez simplement puiser dans la carte elle-même via générique SASS méthodes:

  ...
  property: map-get(map-merge($theme-colors,($key : $color)),$key)
  ...

Une fois que vous avez défini ce KVP particulier, il sera alors disponible globalement pour être utilisé ailleurs.

À ce stade, il est arbitraire d'utiliser CSS var(), mais juste pour couvrir toutes mes bases, vous pouvez définir le thème, puis modifier la variable, au lieu de réinitialiser et d'appeler theme-color("color-2").

Un exemple complet de ceci serait le suivant:

@import "bootstrap";

$theme-colors: (
    "primary": #001122,
    "color-1": black, 
    "color-2": black, 
    "color-3": black 
);

@function set-theme-color($key, $color) {
  @return map-get(map-merge($theme-colors,($key : $color)),$key);
}

@mixin theme($color1, $color2, $color3) {
  background-color: set-theme-color("color-1", $color1);

  h1 {
    color: set-theme-color("color-2", $color2);
  }
  h2 {
    color: set-theme-color("color-3", $color3);
  }
}

main {
  &.theme-purple {
    @include theme(purple,cornflowerblue,white);
    /* example demonstrating color3 can change */
    --color-3: orange;
  }

  &.theme-red {
    @include theme(red,black,white);
  }
}

h2 { 
  color: theme-color("color-2"); 
}
h3 {
/* example demonstrating color3 changed */
  color: var(--color-3);
}
<script src="http://codeply.com/js/embed.js"></script><div data-codeply="o9n2ST6HW5" ></div>

Remarque, l'exemple montre également si un thème définit la variable et d'autres pas. La couleur de thème que vous choisissez n'est pas valide et la propriété revient à hériter.

démonstration en code

6
soulshined

Pourquoi vous ne pouvez pas utiliser de variables CSS pour les couleurs dans SASS

La raison pour laquelle vous n'êtes pas en mesure d'utiliser des variables CSS pour les couleurs est des fonctions telles que darken() et lighten() dans SASS. Vous pouvez imaginer que l'ordinateur ne saura pas quoi faire quand il recevra l'instruction: darken( var(--color), 20%); Vous ne pouvez pas modifier une valeur que vous ne connaissez pas.

Et si nous n'utilisons tout simplement pas des fonctions qui changent de couleur?

En fait, cela devrait réellement fonctionner. La bibliothèque bootstrap possède des fichiers scss qui utilisent ces fonctions. Vous pouvez parcourir tout le code bootstrap et supprimer les fonctions qui modifient les couleurs. Bien sûr, cela être un peu de travail. La mise à jour de bootstrap à l'avenir entraînerait un plantage mystérieux du style de votre site et quelqu'un serait très en colère contre vous. Donc, cette option n'est pas une bonne idée.

Mais ... Mais ... Si CSS peut le faire, vous pouvez avec SASS?

OUI! Telle est la réponse. Et ça va être un peu de travail. Si vous définissez les couleurs à l'aide d'une autre variable, vous pouvez utiliser une variable SASS comme --color pour ces couleurs. Par exemple.:

  $color1: var(--color-1);

  /* It may seem completely redundant to  
     to define CSS variable here. But 
     it isn't. You can change the variables in 
     your browser now with JavaScript, which 
     may affect multiple elements.
  */
  :root{
    --color-1: purple;
  }
  /* An example on how to change the page
     styling with an id.        
  */
  :root#dark-mode{
    --color-1: black;
  }

  .alert-success{
    background-color: $color1;
  }
  .alert-danger{
    background-color: $color1;
  }

Heureusement, les bootstrap 4 développeurs ont fait un très bon travail pour garder leurs sélecteurs simples, donc il ne sera pas trop difficile d'écraser. N'oubliez pas de charger votre CSS après le bootstrap css. Vous pouvez rechercher dans les fichiers bootstrap scss la variable SASS que vous remplacez pour vous assurer de couvrir tous les cas.

Bonne chance!

2
RMo

J'aime mon autre réponse, mais je voudrais également proposer une autre solution, à condition que celle-ci ne réponde pas aux besoins du projet. Une autre option, et je pense plus directe à vos besoins, est que vous pouvez simplement cascader vos feuilles de style. En supposant qu'une arborescence de projet ressemble à ceci:

`css\
  `--main.css
  `--themes.css <- compiled themes.sass
  `--themes.sass
`index.html

index.html:

  ...
  <head>
    <link rel="stylesheet" type="text/css" media="screen" href="css/main.css">
    <link rel="stylesheet" type="text/css" media="screen" href="css/themes.css">
  </head>

  <body>
    <main class="theme-purple">
      <h1>Hello World</h1>
      <h2>SASS is fun!</h2>
    </main>

    <main class="theme-red">
      <h1>Hello World</h1>
      <h2>SASS is fun!</h2>
    </main>
  </body>
  ...

main.css:

.theme-red {
  --theme-color-1: red;
  --theme-color-2: black;
  --theme-color-3: white;
}
.theme-purple {
  --theme-color-1: purple;
  --theme-color-2: cornflowerblue;
  --theme-color-3: white;
}

themes.sass:

@import "node_modules/bootstrap/scss/bootstrap";

$theme-colors: (
  "primary": #001122, 
  "color-1": var(--theme-color-1), 
  "color-2": var(--theme-color-2), 
  "color-3": var(--theme-color-3)
);

main { 
  background-color: theme-color("color-1");
}
h1 { 
  color: theme-color("color-2");
}
h2 { 
  color: theme-color("color-3")
}

De cette façon, vos variables CSS ont pu être compilées. J'ai testé sur un serveur node.js, vous devez donc modifier l'instruction d'importation au besoin

1
soulshined