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.