Sass Maps are Cool

One of the most basic, yet most useful functions of a preprocessor like Sass is the ability to leverage variables in your stylesheets. This little feature can save you lots of time and shield you from many headaches. There are a variety of strategies for using variables, but we’re not going to get too caught up on that type of thing right now. Just so we’re all on the same page, let’s look at an example of a basic variable usage.

$error: #c60b00;

We’ve just assigned the color #c60b00 to the variable $error in our stylesheet. Now we can use that variable anywhere in our stylesheet and if we want to adjust that color we do it in just one place. Fancy.

And here’s how we use it:

.message {
  color: $error;
}

Pretty straightforward, right? Excellent. We’re all on the same page.

Now, on to the cool stuff. Sass version 3.3.0 brought with it a handy new feature called SassScript Maps. These things are pretty powerful and can be used in quite a few interesting scenarios, but today we’re going to take a look at how they can make our work with color variables even easier. Sass maps essentially allow us to create variable groups. We’re going to create a group for our notification colors and expand upon what we currently have.

Here’s our new map:

$notificationColor: (
  $success: #1fa909,
  $warning: #e6a400,
  $error: #c60b00,
);

And here’s how we call the same color as with our standard variable example above:

.message {
  color: map-get($notificationColor, error);
}

You’ll notice we’re using a map-get() function to call the error color from our $notificationColor map. This all works well and I do feel better having some variables grouped together like this. Yeah, the usage ends up being a bit more verbose, but it’s a valid tradeoff for the structure it provides. So I say we’re already winning.

But let’s take things up a notch. In this tiny example we’re dealing with some notification colors. This is a pretty common thing to come across. We will likely have different types of notifications that we’ll want to use in a variety of situations and we want to keep our colors consistent and also make it super easy to make an adjustment if we decide one of the colors isn’t quite right.

We’d likely end up with three variations of our .message from our example. Let’s say .message--success, message--warning, and message--success. Our stylesheet would look like this:

.message--success {
  color: map-get($notificationColor, success);
}

.message--warning {
  color: map-get($notificationColor, warning);
}

.message--error {
  color: map-get($notificationColor, error);
}

We can make this better. What if we want to add a new message? Let’s say .message--info to display some general type of notice. We can add the color to the map and write another class. That works, but we’ve got a new trick up our sleeves because we’ve used a map. We’ll let Sass generate the necessary classes based on the colors that are in our map. Like this:

@each $status, $color in $notificationColor {
  .message--#{$status} {
    color: $color;
  }
}

This @each loop simply looks in our $notificationColor map, loops through everything in it, generates message-- classes, and then adds the associated color property. The generated CSS looks exactly like I had before. The difference is in the maintenance of this code. So to add a new message variant all I’d need to do is declare it in the map and I’d then have access to the class. Same thing to remove one. Take the variable away from the map and the corresponding .message-- class won’t get generated.

It doesn’t take long to see how this method can help keep our code extremely consistent while also being very easy to maintain. By leaving ourselves just one place (our map) to make adjustments it’s actually pretty difficult to be inconsistent. Change a color and it changes everywhere. Add a new color and we have a corresponding (and obviously named) new class at our disposal.

I’m still exploring some other uses for Sass maps, but this is one I’ve used several times and the benefits seem so obvious now. It’s a simple, yet really powerful use case and a great place to try out working with Sass maps. I recommend everyone give a try.