Use Sass 3.3 Maps to Make On-the-Fly Color Guides!

November 15, 2013

Last month, I wrote a little article about the new Sass 3.3 feature @root. That was a lot of fun to explore — and now I want to focus on another sweet feature in Sass 3.3 — MAPS!

HERE’S A LIVE DEMO OF WHAT I’M ABOUT TO WALK YOU THROUGH

To do this, we must first install Sass 3.3:

 gem install sass --pre 

Then, we mark up our HTML:

<ul class="color-list">
    <li class="color-box brick-red"></li>
    <li class="color-box strawberry"></li>
    <li class="color-box deep-orange"></li>
    <li class="color-box tangerine"></li>
    <li class="color-box gold"></li>
    <li class="color-box sunshine"></li>
    <li class="color-box grass-green"></li>
    <li class="color-box lime"></li>
    <li class="color-box funky-purple"></li>
    <li class="color-box clay"></li>
</ul>

I’m using the class “color-box” as a uniform style for each of the colors in my Styleguide, and then classing them with the actual name of the color. We’ll get to the why of it later, but it’s important to keep some consistency in this step.

Now, I style the “color-box” however I want (in this case, I give it a defined size and display: inline-block) etc. etc.. I also give color-box:before and color-box:after a display: block to increase their legibility (in a moment, we’ll get to the good stuff and you’ll see why).

This is where the magic happens (.scss)!

$colors: (
    brick-red: #89231a,
    strawberry: #be1e2d,
    deep-orange: #b94126,
    tangerine: #f16521,
    gold: #eeaf21,
    sunshine: #ffdd17,
    grass-green: #4a893f,
    lime: #8cc63e,
    grape-juice: #452e8b,
    funky-purple: #7e3f98,
    clay: #3b2314,
);

Woah! Look at that Sass Map action! $colors is my map, and it contains a comma-separated list of keys and values ($color: $bgcolor) which I can reference in the each loop. I’m basically going through each key ($color), which is the name of the color (i.e. brick-red), and grabbing it’s $bgcolor hex code (i.e. #89231a). I have access to both elements!

Now, let’s make that baby loop (.scss):

@each $color, $bgcolor in $colors {
    .color-box.#{$color} {
        @include contrasted($bgcolor);
        &:before {
            content: '$#{$color}';
        }
        &:after {
            content: '#{$bgcolor}';
        }
    }
}

Here’s where markup is important: I’m using $color to create the class. You can see this int he 2nd line of the each loop: .color-box.#{$color}. In each of these divs, I then use the Compass contrasted feature, which you can read more about here to set the background color — AND FONT COLOR AT THE SAME TIME! (sorry, I think it’s just such a cool Compass feature)

Then, I use pseudo elements (:before and :after) to read the $color (name) and $bgcolor (hex code) associated with it. So, .color-box:before will have the color’s name inserted into the content (prepended by a ‘$’ to optionally display it like a variable), and .color-box:after contains the hex value ($bgcolor). This is what you get:

CSS Output for one iteration of the loop (one color):

.color-box.strawberry {
  background-color: #be1e2d;
  color: white;
}
.color-box.strawberry:before {
  content: "$strawberry";
}
.color-box.strawberry:after {
  content: "#be1e2d";
}

For further reading, there’s a great example with nesting maps on the Sass 3.3 Changelog and another example of how you can use them in this great article by Jason Garber. Mehdi Kabab also created this pen showing how you can alternatively do all of the above with nested Sass lists instead of maps! Pretty cool :)

TL;DR: Live Demo in Sassmeister