1166Days

1166 days since this post was last revised. Specific details are likely out of date.

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:

20131122-162103.jpg

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.

Don’t forget this is a Sass 3.3 feature (so won’t work with Libsass at present) so get the latest Ruby version of Sass by running `[sudo] gem update sass` from your Terminal.

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.