Sass Sundays: Easy Theme Tiles Using Sass Maps & Lists

As I was browsing Kuler for colour inspiration the other day, I started wondering: what’s an easy way to automate colour theme thumbnail generation with Sass? It took me about half an hour to come up with a widget I was satisfied with and I promptly posted it on Sassmeister.

Take a look at the finished result (and then come back for the detailed writeup).

The HTML is pretty straightforward: a simple unordered list, because that seemed the semantic thing to do. I wanted the whole thing to be as simple as possible, so I just added two classes, theme (which provides the basic styling) and theme--themename, which specifies the theme shown.

<ul class="theme theme--crisp">
  <li>#313340</li>
  <li>#f0f0e3</li>
  <li>#f9c27b</li>
  <li>#ef8531</li>
  <li>#f36519</li>
</ul>

<ul class="theme theme--funky">
  <li>#da0054</li>
  <li>#ff692b</li>
  <li>#fbd726</li>
  <li>#009e8f</li>
  <li>#62b240</li>
</ul>

<ul class="theme theme--autumn">
  <li>#f6484f</li>
  <li>#fbe4b1</li>
  <li>#a9c886</li>
  <li>#417455</li>
  <li>#1d4148</li>
</ul>

And here is the Sass code used to generate the pretty thumbnails:

.theme {
  margin-bottom: 20px;
  font-size: 0; // take care of inline-block whitespace

  li {
    width: 30px;
    height: 30px;
    display: inline-block;

    &:first-child {
      border-radius: 4px 0 0 4px;
    }
    &:last-child {
      border-radius: 0 4px 4px 0;
    }
  }
}

$themes: (
  crisp: #313340 #f0f0e3 #f9c27b #ef8531 #f36519,
  funky: #da0054 #ff692b #fbd726 #009e8f #62b240,
  autumn: #f6484f #fbe4b1 #a9c886 #417455 #1d4148
);

@each $theme, $colours in $themes {
  @for $i from 1 through length($colours) {
    $colour: nth($colours, $i);

    .theme--#{$theme} li:nth-child(#{$i}) {
      background: $colour;
    }
  }
}

I first specify all the common styles in the theme class. This is all pretty simple stuff, except maybe for that font-size: 0 hack which is a handy way to remove the space between inline-block elements. Normally, I would reset this in the li {} rule, but in this case I wanted to hide the list items anyway, so I skipped that.

Then, I use the much anticipated SassScript maps (coming in Sass 3.3) to create a theme collection. Each entry consists of a key (the theme name) and a Sass list used as value (the theme colours). To make it all work, I use two nested loops: for each theme, I go through the colours and assign each of them as the background colour of the appropriate list item. Tada!

So how do I add a new theme? I just add another unordered list with a new theme--themename class and I add the new entry to the $themes map in Sass. Simple as that!

Possible optimizations

This won’t work in Internet Explorer < 8, because nth-child is not supported there. Still searching for the best way to make this backwards compatible, but I don’t expect I’ll lose much sleep over it.

If you need to read more on Sass lists and maps, take a look at Una’s excellent post about generating colour guides as well as these excellent posts by Hugo Giraudel on understanding Sass lists and advanced Sass list functions.

Sass Sundays: A Button Framework for your Projects
Are you a Web Designer? You Should Learn to Code.