Sass Maps and Iterators

One of the top rules for programmers is to stay DRY – don’t repeat yourself. CSS preprocessors are great for helping UI developers accomplish this goal. However, there are still some instances where it seems as if you can’t help but repeat yourself. Here’s a common example of background positions using a sprite:

a {
    background: url(../img/social-media-large.png) no-repeat;
    &.pinterest {
      background-position: -11px -50px;
    }
    &.facebook {
      background-position: -93px -50px;
    }
    &.twitter {
      background-position: -51px -50px;
    }
    &.flickr {
      background-position: -178px -51px;
    }
    &.vimeo {
      background-position: -133px -50px;
    }
    &.youtube {
      background-position: -232px -51px;
    }
  }

Typing “background-position” 6 times is extremely repetitive. However, each icon needs its own background position, so how can we avoid repetition in this situation? Using a Sass map and iterator will keep this code DRY and compact, while creating an easily maintainable chunk of code.

Let’s start by creating the Sass map. Sass maps store key/value pairs that we will use to pair the icon’s class name with its background-position values. Sass maps should be stored in your variables file, since they are like an extended variable.

$social-icons: (
    pinterest: -11px -50px,
    facebook: -93px -50px,
    twitter: -51px -50px,
    flickr: -178px -51px,
    vimeo: -133px -50px,
    youtube: -232px -51px
);

The Sass map is declared with the dollar sign and given a name, just like other Sass variables, and it stores the meat in key/value pairs inside of parentheses and separated by commas. If you compare the two code samples, you will see that the keys in the Sass map match the class names on the icons exactly.

Now that we have defined our Sass map, we have to use it. We will use an iterator to loop through the Sass map and fill in our CSS. This is a very simple example, but we will examine it line-by-line starting from the outside.

@each $icon, $background-position in $social-icons {
   
}

@each is the Sass keyword that sets up our iterator. Following the @each declaration, we have three variables signified by ‘$’. The only familiar variable at this point is the very last one, $social-icons. This is the name of our Sass map that we set up earlier. The other two variables, $icon and $background-position, are new. These are variables that I set up just now in this line of code. Neither of these variables are declared or defined anywhere else. These variables are for use inside of the iterator and can be named however you please. Obviously, the iterator’s syntax will be easier to understand if you pick good, semantic names. The first variable I picked is $icon, signifying each icon’s HTML with a class that I will be targeting. The second variable is $background-position, which signifies the CSS values for background-position that I defined in the map. Each iteration of $icon will be a key in our Sass map, and $background-position will be a value. So we will be iterating through each $icon, $background-position (or key, value) in $social icons, our Sass map.

Let’s add the next line:

@each $icon, $background-position in $social-icons {
   .#{$icon} {
        
   }
}

This syntax will be familiar to Sass users. The first character is a dot, which signifies a class selector in CSS. The rest of the selector represents interpolation syntax in Sass, which is necessary for appending variables to selectors like this. This entire line means that we will be targeting class names that are stored in $icon. So far, our loop will generate the following CSS:

.pinterest {
        
}
.facebook {
        
}
.twitter {
        
}
.flickr {
        
}
.vimeo {
        
}
.youtube {

}

We’re ready to add the final line of our iterator!

@each $icon, $background-position in $social-icons {
   .#{$icon} {
        background-position: $background-position;
   }
}

This line is probably the most familiar of all. This line fills in our selectors with the CSS that we want, which is the values for background-position that match up with the values for $icon. This will take EXACTLY what I’ve put in for the values in my Sass map and fill them in for background-position.

So here is our final product! Exactly what was written at the beginning of the article, but a lot more DRY and maintainable (and not to mention COOL!).

.pinterest {
    background-position: -11px -50px;
}
.facebook {
    background-position: -93px -50px;
}
.twitter {
    background-position: -51px -50px;
}
.flickr {
    background-position: -178px -51px;
}
.vimeo {
    background-position: -133px -50px;
}
.youtube {
    background-position: -232px -51px;
}

The last tie-in I will mention is nesting the iterator. You probably noticed the nesting and use of the ampersand in the first code snippet. These iterators can be nested and combined with the ampersand to achieve the same effect. This decision is completely personal and depends on your views on nesting, since both will output the exact same CSS.

a {
    background: url(../img/social-media-large.png) no-repeat;
    @each $icon, $background-position in $footer-social {
      &.#{$icon} {
        background-position: $background-position;
      }
    }
  }

We just traded 21 lines of code for 8 lines of code. We cut our total lines by more than half! Doesn’t that feel great? Sass maps are extremely powerful. Look for potential usages in your projects!

Emily Lord

I am a UI developer with over 2 years of experience under my belt. I love learning about modern trends and new ways to make beautiful and responsive web pages. My mission is to put a smile on the faces of both the designers and the Sitecore developers while keeping my code clean and efficient. Learn more about Emily.

Add a Comment

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

Or request call back