670Days

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

Until a day before writing this, I had been using Lu Nelson’s quite excellent polyfill for working with data maps in Libsass (and also Ruby Sass 3.3.x and below).

However, as of the latest Libsass (I’m using 3.02) you can use the native map functions of Sass. Woot!

I’m not going into what a map is, or why you would want to use and loop through one. That’s been covered all over the place, including here.

Instead, I just wanted to provide a quick ‘copy and paste’ example, for the way you can loop through a data map and grab the values within.

Without further adieu, here is a basic nested map and loop to spit the values out:

$colourList: (
  id-1: (
    color1: #bbb,
    color2: #ccc
  ),
  id-2: (
    color1: #ddd,
    color2: #eee
  )
);

@each $item, $color in $colourList {
  [data-section-id="#{$item}"] {
  border-top: map-get($color, color1);
  border-bottom: map-get($color, color2);
  }
}

You can play with this yourself and toggle the compiler (just press the cog and switch between Libsass/Ruby Sass) over on Sassmeister.

Whatever compiler you choose, you should see an output resembling this:

[data-section-id="id-1"] {
  border-top: #bbb;
  border-bottom: #ccc; }

[data-section-id="id-2"] {
  border-top: #ddd;
  border-bottom: #eee; }

Now, this little example will be pretty self-explanatory to the full-blown Sass nerds amongst us, but for mere mortals such as myself I’ll explain what’s going on.

First of all we have the data map:

$colourList: (
  id-1: (
    color1: #bbb,
    color2: #ccc
  ),
  id-2: (
    color1: #ddd,
    color2: #eee
  )
);

Much like a JSON object, the map data structure is held in the $colourList variable. Inside, the keys are followed by a colon and then the value. A comma separates each key/value pair (and no trailing comma for the last key/value pair). There are nested key/value pairs and these could also contain nested key/values as needed.

Now the loop:

@each $item, $color in $colourList {
  [data-section-id="#{$item}"] {
  border-top: map-get($color, color1);
  border-bottom: map-get($color, color2);
  }
}

The familiar @each begins the loop, and then the variable $item exists as a marker for the count of the loop (it relates to the dynamic key value that changes as it loops through).

Then for the selector we are interpolating the $item:

If interpolation is unfamiliar to you and you’d like a more thorough explanation I can recommend an incredible book by Ben Frain called, ‘Sass and Compass for Designers‘. Love that guy. So handsome (and modest too).

Now the funky part where we go and grab values. We are using the map-get function.

map-get lets us reach inside a map and grab the values we need. The further nested the data key/value you want, the more you can nest your map-get.

This is obviously a simple example but hopefully if you’re on the Libsass train, it will give you a copy and paste start for using a Sass map and loop when needed.

Finally, a note of caution. Just because you can use a map, doesn’t necessarily mean that you should. They can be a needless complication in some instances. My general rule of thumb is – if I need to loop through and output a bunch of values, I’ll use a map. However, for more pedestrian use cases I’ll just use a bunch of name-spaced variables. For a good discussion on when and where to use a map and the various benefits/pitfalls, this thread is worth a read: https://github.com/zurb/foundation-apps/issues/23