Using lists with Maps in Sass 3.3
OK, I admit it. Sass Maps, a 3.3 feature, are actually pretty useful. Back in this post, I whined that I wouldn’t find them too useful. Only a few days later what do you know? They have saved me an hour of time. Here’s how:
I’d been given a whole bunch of headers (around 150) to style. Each had a background color and unrelated border colour (in that I couldn’t define a relationship between background colour and border in terms of a percentage).
I needed output for each something like this:
.section_1 header {
background-color: #000;
border-right: 2px dotted #111;
}
These values had been sent to me as a JSON file/object. Hopefully you know what I mean. Something like this (actual values have been changed):
var colourList = {
"1" : ["#000000", "#000011"],
"2" : ["#000011", "#000022"],
"3" : ["#000022", "#000033"],
"4" : ["#000033", "#000044"],
"7" : ["#000044", "#000055"],
"8" : ["#000055", "#000066"],
"9" : ["#000066", "#000077"],
"10" : ["#000077", "#000088"],
};
Now, with any decent text editor, it’s fairly easily to manipulate the text to get the values where they were needed for this output but I wanted to see how I could make use of Sass Maps to make the process less hacky (and also enable me to easily update the values if I was sent an amended JSON).
In that JSON format, I couldn’t use the data but with only minor tweaks I’d managed to convert the data to a syntax Sass Maps could make use of:
$colourList: (
1 : (#000000, #000011),
2 : (#000011, #000022),
3 : (#000022, #000033),
4 : (#000033, #000044),
7 : (#000044, #000055),
8 : (#000055, #000066),
9 : (#000066, #000077),
10 : (#000077, #000088),
);
Now for the funky stuff. With the Sass Map made, I needed loop through and get each value. Now I’d seen Chris Eppstein talk about this already and I’d also read @jgarber do a nice walkthrough of using Sass Maps but Jason’s situation didn’t cover using a list within the value part of the key:value pair. To grab the relevant value from here I used the existing Sass list tools. Here’s what the @each loop ended up looking like:
@each $colourList, $keyNumber in $colourList {
$background: nth($keyNumber, 1);
$lowlight: nth($keyNumber, 2);
header {
.section_#{$colourList} & {
background-color: $background;
border-right: 2px dotted $lowlight;
}
}
}
Hopefully this childish sketch shows the relationships I’m describing:
The @each
loop references the list of color (stored as the variable $colourList
) and then references each key as $keyNumber
.
The Sass nth()
function is then used to reference each value in the list that sits within each value ‘pocket’. To reiterate for clarity the part like this (#000000, #000011)
is the list within each value section. So using nth($keyNumber, 1)
I am picking the first item in that list as the value I want to ‘print’ out into the resultant CSS.
As ever, I’m sure there are other (probably better) ways this could have been solved but it was a fairly quick solution I wanted to share.
I had thought I wouldn’t need an article from my comment on CSS-Tricks