Last Updated: February 25, 2016
·
7.423K
· artinruins

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>