Reputation: 138
Can SASS functions be used to generate SASS variables? My intention is to take a small set of colors and process them into many shades and tints of those colors.
N.B. I'm using https://github.com/at-import/color-schemer for the color functions.
I have the following variables:
$root-color: hsl(10, 85%, 45%);
$red: $root-color;
$vermilion: ryb-adjust-hue($red, 30);
$orange: ryb-adjust-hue($red, 60);
$amber: ryb-adjust-hue($red, 90);
$yellow: ryb-adjust-hue($red, 120);
$chartreuse: ryb-adjust-hue($red, 150);
$green: ryb-adjust-hue($red, 180);
$teal: ryb-adjust-hue($red, 210);
$blue: ryb-adjust-hue($red, 240);
$violet: ryb-adjust-hue($red, 270);
$purple: ryb-adjust-hue($red, 300);
$magenta: ryb-adjust-hue($red, 330);
For each color, I'm trying to produce the following output ($red
shown below):
$red-10: $red;
$red-01: shade($red-10, 90);
$red-02: shade($red-10, 80);
$red-03: shade($red-10, 70);
$red-04: shade($red-10, 60);
$red-05: shade($red-10, 50);
$red-06: shade($red-10, 40);
$red-07: shade($red-10, 30);
$red-08: shade($red-10, 20);
$red-09: shade($red-10, 10);
$red-11: tint($red-10, 10);
$red-12: tint($red-10, 20);
$red-13: tint($red-10, 30);
$red-14: tint($red-10, 40);
$red-15: tint($red-10, 50);
$red-16: tint($red-10, 60);
$red-17: tint($red-10, 70);
$red-18: tint($red-10, 80);
$red-19: tint($red-10, 90);
I can boil this down to the following:
For each $color
:
$red-10: $red;
For 1 - 9 ($1)
: Generate variable $#{$color}-0$1: shade($red-10, (100 - ($1 * 10)))
For 1 - 9 ($1)
: Generate variable $#{$color}-($1 * 10): tint($red-10, ($1 * 10))
Obviously I get an error:
Error: Invalid CSS after "...m 1 through 9 {": expected 1 selector or at-rule, was "#{$color}-$1: shade"
I've looked into using lists and @append
but as I have x colors I'm thinking I'd have to create dynamic lists? Is that even possible?
I'm aware that I'm both using a variable to create a variable ($#{$color}
)and trying to output a function within the loops, and am not sure if this is even possible with SASS.
If not, is there a better workflow for this kind of thing?
Upvotes: 1
Views: 3107
Reputation: 4335
Currentry Sass does not allow to access or create variables dynamically. The only way to achieve so, is to use maps. And, if you have a variable number of colors, then you could use a map where each key (the color name) contains a list of all the generated colors, so you could keep track of them.
Note i changed the color functions and values for testing purposes only (changed shade
to lighten
and tint
to darken
; also in the the tint
loop, i added a - 100
to the value, to keep the darken value between 1 and 100). You should replace those functions with yours.
// Colors to use
$colors:(
red: red,
blue: blue
);
// Generated color lists
$generated: ();
// For each defined color
@each $name, $color in $colors {
// Current color map
$current : ();
// Generates the colors transformations (shades)
@for $i from 1 through 9 {
$current: append($current, lighten($color, (100 - ($i * 10))));
}
// Adds the current color
$current: append($current, $color);
// Generates the colors transformations (tints)
@for $i from 11 through 19 {
$current: append($current, darken($color, ($i * 10) - 100));
}
// If the map has not been created
@if map-has-key($generated, $name) == false {
$generated: map-merge($generated, ($color : $current));
}
}
// Create a function to get the desired color
@function get-color($color, $index: 10) { // Default to base color
// Get the desired color map
$list: map-get($generated, $color);
// Return the color index
@return nth($list, $index);
}
Then you could use the created function to get the color idex of your choice:
.foo {
color: get-color(blue, 5);
}
You can check the working example here.
Hope it helps.
Upvotes: 4