Make a @for-each loop in Compass/SCSS
Sometimes, its fun to be tricky. I had a site design that features a differently colored menu bar per section of the site. As you can imagine, I had a lot of repetitive code. I wondered if there was a way to make a @for-each
loop in Compass, and to my surprise, there is... sort of.
A true @for-each loop
is not possible (yet), but, a set of associative arrays is possible and very handy when there are multiple things that need to be looped on. Here is a simplified example of what I ended up setting up for this project:
Associative Arrays in Compass/SCSS
$names: menu1, menu2, menu3;
$colors: $blue, $green, $purple;
@for $i from 1 through length($names) {
$this-color: nth($colors, $i);
.#{nth($names, $i)}-navigation {
@include background-image( linear-gradient( $this-color, 30%, adjust-lightness( $this-color, -8 ), 95% ) );
border-top: 1px solid lighten($this-color, 15%);
border-bottom: 1px solid darken($this-color, 25%);
}
}
A quick run down:
First, we set up the arrays. We need two of them (at least) and we need to values for the first, second, third (etc…) items to correspond – as in, you want menu1
to use the color $blue
.
Then, the @for
loop opens. If you are familiar with PHP or other languages, you can recognize how this works. The length()
function acts like count()
in other languages, and figures out the number of items that you have in your array.
Then, for ease of use, I set $this-color
to the array value at the value of the counter. In PHP, it would be $this-color = $colors[$i];
Finally, we start writing CSS. I use the values in the $names
array to set the name of the wrapper class. Inside that, we simply use Compass functions to vary the base color to create a unique menu bar style.
Ideas on how to do this were borrowed from a discussion on the Compass Github project: <a href="//github.com/nex3/sass/issues/132#issuecomment-4335097">github.com/nex3/sass/issues/132#issuecomment-4335097</a>