Consider I have a long list of SASS variables in different .scss files like this:
$app-color-white: #ffffff;
$app-color-black: #000000;
What would be the most effective way to export these variables as vanilla CSS variables?
:root {
--app-color-white: #ffffff;
--app-color-black: #000000;
}
Maybe, there is a SASS-way or even some pre-processor?
I want my SASS framework to be also used in vanilla CSS projects.
This is now possible thanks to sass modules and the new sass:meta.module-variables() function: it
Returns all the variables defined in a module, as a map from variable names (without $) to the values of those variables.
For example
// _vars.scss
$color: red;
$font: Helvetica, sans-serif;
// style.scss
#use 'sass:meta';
#use 'vars';
:root {
#each $name, $value in meta.module-variables(vars) {
--#{$name}: #{$value};
}
}
Outputs
:root {
--color: red;
--font: Helvetica, sans-serif;
}
⚠️ Sass modules are currently only supported in Dart Sass
I think the best way to do this would be using something like a variable map;
E.g.
// sass variable map
$colors: (
primary: #FFBB00,
secondary: #0969A2
);
// ripped CSS4 vars out of color map
:root {
// each item in color map
#each $name, $color in $colors {
--color-#{$name}: $color;
}
}
Output:
:root {
--color-primary: #FFBB00;
--color-secondary: #0969A2;
}
Source: https://codepen.io/jakealbaugh/post/css4-variables-and-sass
Related
I'm currently trying to do a mutliple theme design system with bulma as a base.
But i'm currently struggling with adding a multiple theme system.
I added this in my customstyle scss file but it doesn't seems to work
#charset "utf-8";
:root {
--primary: red;
--secondary: #068295;
}
body[class="light"] {
--primary: #F7A800;
--secondary: #068295;
}
body[class="dark"] {
--primary: blue;
--secondary: #068295;
}
$primary: var(--primary); // this works
$background: blue;
$text-strong: red;
$secondary: #8BC91D; // this works but without theming
// $secondary: var(--secondary); // this doesn't work
$secondary-invert: findColorInvert($secondary) !default;
$custom-colors: (
"secondary":($secondary, $secondary-invert),
);
#import "../node_modules/bulma/sass/utilities/_all.sass";
#import "../node_modules/bulma/sass/base/_all.sass";
#import "../node_modules/bulma/sass/elements/button.sass";
when I run the node sass command to generate the css file
i can see the is-secondary properties generated when i don't use the variable but when i use a variable to define my $secondary variable the is-secondary properties are not generated
Is there a way to override variables in SCSS without mixins or functions?
My setup looks like this:
Input:
$color: red !default;
selector {
color: $color;
}
$color: blue;
Output:
selector {
color: red;
}
I already tried to use !global but this does not work either.
I am not sure, if this is even possible in SCSS without using mixins.
You need to set the variable before it gets declared with !default.
To achieve the result you want your code needs to look like this:
$color: blue;
$color: red !default;
selector {
color: $color;
}
Here is some info about how !default works.
I'm trying to do the following in sass (scss),
$colors-#{$type}
but I get
undefined variable $colors-
I found a source that was refering to the 3.3 release document, they do mention it, however, I can't find the solution to the issue.
Is there a way to do this?
link to scss
I think the post is misleading. Each issue I found on Github (for instance here or here) recommend the use of a map. And on https://github.com/sass/sass/issues/463 one of the contributors wrote:
We've decided to add an association data type (aka map/hash) and it will address this use case.
Use a map and map-get() to get your style definitions dynamically. You can use it within a mixin, a function or directly. The following example
$colors: (
"green": #0c0,
"blue": #00c,
"red": #c00
);
#mixin my_color($color) {
color: map-get($colors, $color);
}
#function my_color_func($color) {
#return map-get($colors, $color);
}
body {
#include my_color("green"); // use a mixin
background-color: my_color_func("blue"); // use of a function
border: 1px solid map-get($colors, "red"); // use directly
}
generates the following css:
body {
color: #0c0;
background-color: #00c;
border: 1px solid #c00;
}
Previously in SCSS (version 3.4.21), I can use variable interpolation to get a specific item from a map:
$colors: (
color-1: #aaa,
color-2: #bbb,
color-3: #ccc
);
#mixin color($shade) {
color: map-get($colors, #{color-}$shade );
}
.element {
#include color(2);
}
Compiles to:
.element {
color: #bbb;
}
Playground Link
In sass 4 (alpha), it doesn't work (or i'm screwing something up):
#{color-}$shade
It doesn't allow me to do that. Is there a reason this was taken out?
I think your syntax is just a bit backwards.
#mixin color($shade) {
color: map-get($colors, gray-#{$shade} );
}
I am declaring variable of same name in two files. I import them in a following order and found a conflict.
Modal.scss
$gray : #e1e1e1; // Imported first
Variable.scss
$gray : #999; // imported later
The expected behaviour is that the value of $gray be overwritten. However, I am getting the firstly imported value (#e1e1e1) instead of (#999) in CSS.
Am I doing the wrong thing declaring variable multiple times?
Apparently, Sass will take first variable declaration.
For example when you use Bootstrap in Sass, you have to declare all variables you want to override before you import Bootstrap.
// This will override the default $brand-primary in Bootstrap
$brand-primary: #000;
// Importing Bootstrap
#import 'bootstrap';
Quick notes on SCSS variables
When processed Sass will output the current variable value
$color: red;
.class-1 { color: $color; } // red
$color: blue;
.class-2 { color: $color; } // blue
You can use the !default flag to define default variables.
$color: red;
$color: blue !default; // only used if not defined earlier
.class-1 { color: $color; } // red
Inside function, mixins and selectors variables are local.
$color: red; // global
#mixin color {
$color: blue; // local
color: $color
}
.class-1 { color: $color; } // red (global)
.class-2 { #include color; } // blue (local)
.class-3 {
$color: green; // local
color: $color; // green (local)
}
.class-4 {
color: $color; // red (global)
}
You can use the !global flag to globalize variables.
$color: red; // global
#mixin color {
$color: blue !global; // global
color: $color
}
// as we are including color after printing class-1 the color is still red
.class-1 { color: $color; } // red
.class-2 { #include color; } // blue
// at this point the include in class-2 changed the color variable to blue
.class-3 { color: $color; } // blue
i think you should modified color name like light-gray: #e1e1e1; and dark-gray: #999;. this will help for solve your problem.
You should keep your variable names unique to reduce conflicts.
try:
$gray : #999 !important;