An approach for Sass: pseudo-dictionaries
Via: http://kevinwolf.me/blog/sass-pseudo-dictionaries/
One of the things that I don't love about Sass is its lack of support for the use of dictionaries or associative arrays.
This isn't an official approach, and I sincerely don't remember to have read about it. It is about trying to simulate a key => value
dictionary, by creating a comma-separated list and assigning it to a variable.
Implementing it
For start using this approach, we need:
- A pseudo-dictionary.
- A function to retrieve a value from dictionaries.
The pseudo-dictionary
It is a simple Sass list in which we will separate every key => value
pair with a comma. For example, we will create our color pallete list.
$colors :
apple #c0392b,
sky #2980b9,
turquoise #1abc9c,
wet-asphalt #34495e
;
Now, we can retrieve a color from the list by it's numeric index using Sass's nth-child function, although this isn't a recommended practice because it will depend on the item position, and this position can change when we add new colors to the list.
.page-background {
$bg-item : nth($colors, 1); // apple #c0392b
$bg : nth($bg-item, 2); // #c0392b
$foreground-item : nth($colors, 4); // wet-asphalt #34495e
$foreground : nth($foreground-item, 2); // #34495e
background-color : $bg;
color : $foreground;
}
The getter function
To avoid the previous code block approach, we need to create a simple Sass function which should receive a key name and return it's value.
@function getColor ($colorName) {
// Run across the color list.
@each $color in $colors {
// If the key (first child of the current $color) is
// the same as the specified by params, return the value.
@if nth($color, 1) == $colorName {
@return nth($color, 2);
}
}
}
Now, we can return the color value on a cleaner way using that function.
.page-background {
background-color : getColor(apple);
color : getColor(wet-asphalt);
}
Bonus: Object Oriented Sass all the way!
Now that you know how to simulate dictionaries in Sass, let's take advantage of this practice by creating some object oriented classes.
// Run across the colors dictionary to create both
// text-color classes.
@each $color in $colors {
.text-#{nth($color, 1)} {
color : nth($color, 2);
}
}
Or, if you are a nerd, you can easily generate both background and foreground color classes on 7 lines.
@each $feat in "background-color", "color" {
@each $color in $colors {
.#{$feat}-#{nth($color, 1)} {
#{$feat} : nth($color, 2);
}
}
}
Source code.
You can check the code of this tutorial at this SassMeister gist.
Written by KevinWolf
Related protips
3 Responses
Kevin, this is frickin' boss. I was feeling doubtful until I took a look at my css and every color matched up to my classes. This is going to make setting background colors by class a breeze.
If you're only interested in SCSS extension you can replace the "." in your generator functions with "%" to create placeholder classes. Thanks for this, really handy.
Thank you - this is exactly what I was looking for.