Real Sass, Real Maps

Adventure seekers describe a map as a guide. A symbolic depiction highlighting relationships between elements of some space, such as objects. To travelers, maps are a must and soon you’ll discover the powerful benefits of using maps as well, but with Sass. Sass maps are about to become your new BFF and here’s why.

Maps in Sass

Introduced in Sass 3.3, maps represent an association between keys and values within an object. Maps must always be surrounded by parentheses and the key/value pairings inside must always be comma-separated. Once a map has been created authors have the ability to loop through the map (or not) and distribute these key/value pairings at will. Both the key and the value in Sass maps can be any SassScript object (native Sass functions that allow authors to manipulate code). Here’s what the basic structure looks like…

$map: (
  key1: value1,
  key2: value2,
  key3: value3
);

@each $key, $value in $map {
  .element--#{$key} {
    background: $value;
  }
}
Figure 1 : Sass map setup structure

By using the powers of descriptive words(wink, wink) I hope the example above makes sense. As we loop through our map using @each, the first value is the map’s key followed by the key’s value and finally the variable ($map) representing our map. It’s also good to note that we don’t always need a loop to obtain the map’s keys/values, but it’s good to see how a loop can be used.

Maps In Real Life

Discussing how something works is one thing, but seeing how it can be used in real life is a different beast entirely. I’m the type that needs to see some real action and foo nor bar will do. Let’s take a look at some real cases using real words to describe real things.

Multiple Transition Values

Transitions have the ability to receive multiple values separated by a comma so lets take a transition that might be used widely across our system and make a map representing the behavior we’re trying to achieve.

Sass

$card_morph: (
  trans1:  200ms transform ease-in-out,
  trans2: 400ms background ease-in,
  trans3: 600ms color linear
);

.card {
  transition: map-values($card_morph);
}
Figure 2 : Multiple transition values for a behavior using a Sass map

CSS Output

.card {
  -webkit-transition: 200ms -webkit-transform ease-in-out, 400ms background ease-in, 600ms color linear;
          transition: 200ms transform ease-in-out, 400ms background ease-in, 600ms color linear;
}
Figure 2a : CSS output for multiple transition values using a Sass map.

The function map-values() used above works like this…it will return a list of all values in a map comma-separated (not including the keys). The parameter accepted is the map itself so in this case that’s the variable we defined called $card_morph. Also take note that we’re not using a loop in this case. We’re simply using the Sass Script Function natively built into the language.

Multiple Maps, One Loop

We can use multiple maps within one loop as well. This can be great for objects that carry properties in relation to one another. In this case, eye color and font based on the particular name of a person.

Sass

$eye_color: (
	jeremy: #0989cb,
	beth: #8666ae,
	matt: #02bba7,
	ryan: #ff8178
);

$font: (
	jeremy: Helvetica,
	beth: Verdana,
	matt: Times,
	ryan: Arial
);

@each $key, $value in $eye_color {
	.#{$key} {
		background: $value;
		font-family: map-get($font, $key);
	}
}
Figure 3 : Multiple maps, one loop Sass example

CSS Output

.jeremy {
  background: #0989cb;
  font-family: Helvetica;
}

.beth {
  background: #8666ae;
  font-family: Verdana;
}

.matt {
  background: #02bba7;
  font-family: Times;
}

.ryan {
  background: #ff8178;
  font-family: Arial;
}
Figure 3a : Multiple maps, one loop CSS output

I’m sure you may have noticed the SassScript Function map-get() from the loop above. The map-get function allows authors to retrieve the value of the key requested. The first parameter is the map desired and the second is the key of the map requested. This is why we can obtain the output of another map from the same loop since the keys in both maps are identical.

Config Maps

Here’s an example I use in my demo for a Google Material Design interaction. In this case we use maps as a configuration object in order to obtain and set the different properties of the object.

Sass

$google_materialshadow_ambient: (
  shadow1: 0 1px 1.5px rgba(0, 0, 0, 0.12),
  shadow2: 0 1px 1px rgba(0, 0, 0, 0.24)
);

$google_materialshadow: (
  ambient: map-values($google_materialshadow_ambient)
);

$google_expando_proportions: (
  icon_size: 24px,
  card_size: 340px
);

.google-expando__icon {
  box-shadow: map-get($google_materialshadow, ambient);
  height: map-get($google_expando_proportions, icon_size);
  width: map-get($google_expando_proportions, icon_size);
}
Figure 4 : Sass maps used as a configuration object

Hopefully by now things are starting to look familiar. Nothing has changed in what’s being used it’s just a different approach to a different context. We’re still using map-get() and map-values(), but we’re using our maps to hold and store information based on characteristics of an object. Also note the use of a map ($google_materialshadow_ambient) within a map ($google_materialshadow) in order to store the type of shadow effect we desire.

Icon Fonts

Want a DRY approach to write and generate content for your pseudo trickery in order to achieve icon font bliss?

Sass

$icons: (
  menu: "\fXXX",
  delete: "\fXXX",
  search: "\fXXX"
);

@each $icon, $unicode_value in $icons {
  .transformicons-#{$icon}:before {
    content: $unicode_value;
  }
}
Figure 5 : Icon font bliss using 1 loop to write different pseudo content values

Tracking Layers

Here’s a fun way to track your z-index issues. In this case I’m using a table and sandwich as a means to convey meaning to my layers. Keep in mind z-index works much like items on a table.

Sass

$layers: (
  ground: -3,
  basement: -2,
  floor: -1,
  table: 0,
  bottom_bun: 1,
  condiment: 2,
  cheese: 3,
  meat: 4,
  top_bun: 5
);

.container {
  position: relative;
  z-index: map-get($layers, table);
}

.container__modal {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  z-index: map-get($layers, top_bun);
}

HTML

<div class="container">
  This is the container
  <div class="container__modal">This is the modal</div>
</div>
Figure 6 : z-index battle Sass and HTML

Do you have an amazing way to use a Sass map? Leave a comment and help us discover the deepest power of our new BFF.

References

Dennis Gaebel

Design Technologist passionate for Open Source, SVG, Typography, Web Animation, Interaction Development & Pattern Based Design. http://droidpinkman.io.
  1. Another great example and use case of a Sass map can be seen on my Cascader demo on CodePen that takes a comma separated list returned by map-values() and uses the zip() method to convert the comma separated list into a space separated list for the animation property.

    $cascade-effect: (
      name: cascade,
      timing: 2s,
      length: infinite,
      direction: forwards
    );
    
    .cascader__item {
      animation: zip(map-values($cascade-effect)...);
    }
    .cascader__item {
      animation: cascade 2s infinite forwards;
    }
    1. Clever. I like it.

      1. Thanks Hugo.

Leave a Reply

Your email address will not be published. Required fields are marked *

show formatting examples
<pre class="language-[markup | sass | css | php | javascript | ruby | clike | bash]"><code>
…code example goes here…
</code></pre>

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comment Preview

  1. John Doe shouted this comment preview:
    2014/12/16