'Create CSS custom properties from SCSS variables
I have an SCSS map of colour names and values. I want to create CSS custom properties from them like so:
SCSS
$colours:(
"gray-500": #f7fafc,
"red-500": #f56565,
"green-500": #48bb78
);
Desired resultant CSS
--gray-500: #f7fafc;
--red-500: #f56565;
--green-500: #48bb78;
I know how to loop through the map, but where I'm getting caught up is how to use the key as a custom property name, and how to prepend --
to it. All the examples I can find related to this topic involve manually typing out the custom property name - not gleaning it from the key of a map.
This is what I have so far:
@each $colour, $value in $colours {
--#{$colour}:$value;
}
That generates an error: expected "{"
with the caret pointing to the end of this line:
--#{$colour}:$value;
I'm using Dart Sass 1.23.7
Solution 1:[1]
On SCSS to CSS you can use the following:
:root {
$colours:(
"gray-500": #f7fafc,
"red-500": #f56565,
"green-500": #48bb78
);
@each $key_name, $value in $colours {
--#{$key_name}: #{$value};
}
}
On SASS to CSS you have to use the @each
inside a :root
element (or defining an element inside):
$colours:(
"gray-500": #f7fafc,
"red-500": #f56565,
"green-500": #48bb78
);
:root {
@each $key, $value in $colours {
--#{$key}: #{$value};
}
}
Solution 2:[2]
If you want to create CSS custom properties from nested sass map, you can do the following:
@use "sass:meta";
// create mixin
@mixin map-scss-vars-into-css-vars($map, $prefix, $key: "") {
@each $name, $value in $map {
// copy the map key
$key-copy: $key;
// create name for CSS custom property that contains:
// current key + child key from nested map
$key: #{$key}-#{$name};
@if meta.type-of($value) == "map" {
// if value is a map, invoke it once more
@include map-scss-vars-into-css-vars($value, $prefix, $key);
} @else {
--#{$prefix}#{$key}: #{$value};
}
// next iteration of loop should go with unchanged key
$key: $key-copy;
}
}
How to use
// define your nested map
$config: (
button: (
primary: (
color: red,
background: blue,
),
secondary: (
color: yellow,
background: green,
),
tertiary: (
color: white,
background: black,
),
),
input: (
primary: (
width: 100px,
),
),
);
// include magical mixin
:root {
@include map-scss-vars-into-css-vars($config, 'my-cool-app');
}
// the result is astonishing
--my-cool-app-button-primary-color: red;
--my-cool-app-button-primary-background: blue;
--my-cool-app-button-secondary-color: yellow;
--my-cool-app-button-secondary-background: green;
--my-cool-app-button-tertiary-color: white;
--my-cool-app-button-tertiary-background: black;
--my-cool-app-input-primary-width: 100px;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Piosek |