I'm implementing a websites style.
For legacy support reasons, I need to support IE11, at least for a while. For workflow and my sanity reasons, I would like to use css variables where possible.
I have looked at this solution, which would generate something that works, but it is quite verbose to use.
My goal is to end up with a hardcoded value, which is overwritten by a CSS variable immediately. This way I can add a default theme for everyone, and different themes (like darkmode) for those browsers that support css variables. Obviously without needing to write all of that myself.
So the idea would be that I can write something like this:
$foo {...?}
:root {
--foo: red;
}
:root.dark {
--foo: black;
}
p {
color: $foo;
}
and it gets transpiled to
:root {
--foo: red;
}
:root.dark {
--foo: black;
}
p {
color: red;
color: var(--foo);
}
Is this possible with scss? I do not want to add some random npm modules or other third party compilers and transpilers to this project to bloat it.
I know of the possibility of adding a polyfill for IE11 that adds support for CSS variables, but most that I've found so far have some form of unfortunate limitation (plus again, they are third party code that I would prefer to avoid if I can). If there is no nice solution using SCSS, that is probably what I will go with.
CodePudding user response:
Here is a quick solution you might want to improve:
- Define a map with all your colors:
$colors: ("blue": #0000ff, "red": #ff0000, "green": #00ff00);
- Loop over the map to create the css custom properties:
@each $color, $value in $colors {
:root {
--#{$color}: #{$value};
}
}
- Create a mixin to output both the fallback and the value.
I've decided to create a mixin that takes 2 params, the css property and the color you want.
@mixin propertyPlusColorValue($property, $color) {
#{$property}: map.get($colors, $color);
#{$property}: var(--#{$color});
}
- Then you can use it like this:
.foobar {
@include propertyPlusColorValue(color, "blue");
@include propertyPlusColorValue(background-color, "red")
}
Full code:
@use "sass:map";
$colors: ("blue": #0000ff, "red": #ff0000, "green": #00ff00);
@each $color, $value in $colors {
:root {
--#{$color}: #{$value};
}
}
@mixin propertyPlusColorValue($property, $color) {
#{$property}: map.get($colors, $color);
#{$property}: var(--#{$color});
}
.foobar {
@include propertyPlusColorValue(color, "blue");
@include propertyPlusColorValue(background-color, "red")
}