Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Loops: @each and @for

A loop repeats a block of code for every item of a list or for every number in a range. In Sass loops are used to generate CSS: one short loop turns into dozens of similar classes — colours, gaps, column widths. The browser gets the finished classes.

Interpolation

To make a class name from a value, insert it into the selector with #{}. This is interpolation:

// styles/main.scss
$name: "primary";
 
.text-#{$name} {
  color: #2563eb;
}
.text-primary {
  color: #2563eb;
}

Without the brackets, .text-$name is a syntax error: in a selector Sass does not look for variables.

@each over a list

@each takes the items of a list one by one into a variable. Utility classes get their own folder; create styles/utilities/_text-align.scss:

// styles/utilities/_text-align.scss
@each $align in left, center, right {
  .text-#{$align} {
    text-align: $align;
  }
}
// styles/main.scss
@use "utilities/text-align";
.text-left {
  text-align: left;
}
 
.text-center {
  text-align: center;
}
 
.text-right {
  text-align: right;
}

Three rules from four lines. Adding justify to the list adds the fourth class.

@each over a map

With a map the loop takes two variables — the key and the value. Here the theme colours become text and background classes:

// styles/utilities/_colors.scss
$colors: (
  "primary": #2563eb,
  "success": #16a34a,
  "danger": #dc2626,
);
 
@each $name, $color in $colors {
  .bg-#{$name} {
    color: white;
    background: $color;
  }
}
// styles/main.scss
@use "utilities/colors";
.bg-primary {
  color: white;
  background: #2563eb;
}
 
.bg-success {
  color: white;
  background: #16a34a;
}
 
.bg-danger {
  color: white;
  background: #dc2626;
}
<style>
  .bg-primary {
    color: white;
    background: #2563eb;
  }
 
  .bg-success {
    color: white;
    background: #16a34a;
  }
 
  .bg-danger {
    color: white;
    background: #dc2626;
  }
</style>
 
<p class="bg-primary">Information</p>
<p class="bg-success">Saved</p>
<p class="bg-danger">Error</p>

@for — counting

@for repeats a block for numbers in a range. from 1 through 4 includes 4; from 1 to 4 stops before it. Here is a margin scale with a step of 8px:

// styles/utilities/_spacing.scss
@for $i from 1 through 4 {
  .mt-#{$i} {
    margin-top: $i * 8px;
  }
}
// styles/main.scss
@use "utilities/spacing";
.mt-1 {
  margin-top: 8px;
}
 
.mt-2 {
  margin-top: 16px;
}
 
.mt-3 {
  margin-top: 24px;
}
 
.mt-4 {
  margin-top: 32px;
}

Which loop to choose

TaskLoop
Classes from a list of words@each $item in ...
Classes from named values@each $key, $value in $map
Numbered classes: .mt-1, .col-6@for $i from 1 through N

There is also @while, which repeats while a condition is true, but @each and @for cover almost every case and cannot loop forever.

Common mistake

Loops make it easy to generate far more CSS than the site uses. Ten colours times six properties times five breakpoints is three hundred classes, most of them never used, and the CSS file becomes heavy. Generate only what the design needs, and check the size of the compiled file after adding a loop.

Thanks for reading!

Donate to the site — we work hard for you.