Max Glenister

Web Dev • 4 min read Plain text

Getting to know @for, @each and @while in Sass

I use Sass every day, both professionally and in my side projects. One thing that never seems to stick in my mind though is the correct way to use @for, @each or @while.

I’m writing this up here for some cathartic release, and hopefully to be of use to somebody else.

The @for directive

In Sass, @for will let you iterate over a range of values. If you’re familiar with using afor loop in JavaScript to loop over an Array(), this should be very familiar.

For example, this:

@for $num from 1 through 4 {
  .element-#{$num} {
    width: $num * 10%;
  }
}

Will generate this:

.element-1 {
  width: 10%;
}
.element-2 {
  width: 20%;
}
... etc.

You’ll notice that the value for $num can be used within the loop too, so in my example I’m using it to calculate the value for width each time.

You could also use @for to loop through a data object, such as a list/array, and pull values out by index:

$list: red, green, blue, orange, brown;
$length: length($list);
@for $num from 1 through $length {
  .element-#{$num} {
    background-color: nth($list, $num);
  }
}

Will generate this:

.element-1 {
  background-color: red;
}
.element-2 {
  background-color: green;
}

... etc.

It’s worth noting here that in Sass, lists are 1-based, rather than 0-based, so we start from 1.

Besides the through syntax, you can also use the to syntax @for $num in <x> to <y>. The difference between through and to is that through will include the last index, and to will exclude the last index.

Through

@for $num from 1 through 4 {
  .element-#{$num} {}
}
.element-1 {}
.element-2 {}
.element-3 {}
.element-4 {}

To

@for $num from 1 to 4 {
  .element-#{$num} {}
}
.element-1 {}
.element-2 {}
.element-3 {}

Further reading: length(), nth(), @for.

The @each directive

In Sass, @each will allow you to iterate over each item in a list. This is similar to foreach in JavaScript:

$list: spoon, fork, knife, cup;
@each $item in $list {
  .#{$item} {

  }
}

Will generate this:

.spoon {}
.fork {}
.knife {}
.cup {}

When you’ve got multidimensional lists you can assign more than one variable:

$list: (red, 2, spoon), (blue, 4, fork), (green, 6, knife), (yellow, 8, cup);
@each $color, $number, $item in $list {
  .#{$item} {
    background-color: $color;
    width: $number * 10%;
  }
}

To generate:

.spoon {
  background-color: red;
  width: 20%;
}
.fork {
  background-color: blue;
  width: 40%;
}
... etc.

This is really useful for using complex data structures to generate style declarations really quickly. An applied use of @each might look something like this:

$flags: (england, en), (france, fr), (germany, de), (spain, es);

@each $country,$code in $flags {
  .flag-#{$code} {
    background-image: url(flags/#{$country}.png);
  }
}

Which generates classes for semi-transparent PNG background images:

.flag-en {
  background-image: url(flags/england.png);
}

.flag-fr {
  background-image: url(flags/france.png);
}
... etc.

Further reading: @each

The @while directive

The @while directive takes an expression, and continues to loop until that expression is false. This is identical to while in JavaScript.

Here’s a simple example, comparing $width to $maxWidth, and running while $width is less than or equal to $maxWidth.

$width: 0;
$maxWidth: 100;

@while $width <= $maxWidth {
  .width-#{$width} {
    width: $width * 1%;
  }
  $width: $width + 10;
}

Generates this:

.width-0 {
  width: 0%;
}

.width-10 {
  width: 10%;
}

.width-20 {
  width: 20%;
}
... etc.

Further reading: @while

  • Web Dev · shares #css
    Better link underlines with Sass

    There has been some talk lately about how iOS 8 has started to handle typography descenders when text is underlined. They’ve done away with the usual overlapping line intersect in favour of a more aesthetically pleasing line crop.

    November 2014 • 3 min read
  • Web Dev · shares #css
    Some approaches for creating diagonal section separators for your website

    In their simplest form, web pages are made of stacked rectangles. Every block-level element takes up as much vertical space as the content requires, and fills as much horizontal space as is available. Additionally, block-level elements can have their width/height specified. When you have absolutely positioned, or floated elements this changes a bit but the rule pretty much sticks.

    May 2014 • 5 min read
  • Web Dev · shares #guide
    Getting started with using Sass in your existing website

    Sass is a CSS-compatible preprocessor for CSS. It allows you to reduce the amount of duplication and complexity in your CSS by using variables, mixins (functions), nesting, and other cool things that should have existed in the CSS spec from the beginning.

    January 2014 • 5 min read

Discussion

No interactions yet

Join the conversation

Reply from your own site with a Webmention (how?).

Webmentions last fetched 13 November 2026, 07:47