Skip to content

The Sass @for Loop

The @for loop repeats a block a fixed number of times, counting through a numeric range. This lesson covers through vs to, and shows practical examples like generating a numbered column grid or a spacing scale.

How the @for Loop Works

@for counts from a start value to an end value, running its block once per iteration with a loop variable set to the current count. It's the right tool whenever you know exactly how many times you need to repeat a pattern.

@for $i from 1 through 4 {
  .col-#{$i} {
    width: math.div(100%, 4) * $i;
  }
}

This generates four rules, .col-1 through .col-4, each with its own computed width based on the loop variable $i.

@for Syntax: through vs to

@for $i from 1 through 3 { ... } // includes 3
@for $i from 1 to 3 { ... }      // stops before 3, includes only 1 and 2
  • through includes the end value in the loop.
  • to excludes the end value, stopping one short.
  • The loop variable ($i above) is scoped to the loop's block.
  • @for can count downward too, by using a start value larger than the end value.

@for Loop Cheatsheet

Common @for patterns for generating grid systems and numbered utilities.

Pattern Example Generates
Inclusive range @for $i from 1 through 12 1, 2, 3, ..., 12
Exclusive range @for $i from 1 to 12 1, 2, 3, ..., 11
Grid columns .col-#{$i} { width: ... } 12-column grid utilities
Z-index scale .z-#{$i} { z-index: $i * 10; } Stepped z-index utilities
Descending loop @for $i from 5 through 1 5, 4, 3, 2, 1

Generating a Numbered Grid System

One of the most practical uses of @for is generating a complete set of grid column classes without writing each one by hand, a pattern used internally by many CSS frameworks.

@use 'sass:math';

$grid-columns: 12;

@for $i from 1 through $grid-columns {
  .col-#{$i} {
    width: math.div(100%, $grid-columns) * $i;
  }
}

Generates .col-1 through .col-12, each sized proportionally to its column count.

Generating a Spacing Scale

@for also works well for generating a full spacing utility scale, margin or padding classes at fixed increments, without manually repeating the same declaration pattern for every step.

@for $i from 0 through 5 {
  .m-#{$i} {
    margin: $i * 0.25rem;
  }
}

Counting Downward

@for doesn't require counting upward, reversing the start and end values counts downward instead, useful for generating descending z-index stacks or reverse-numbered utilities.

@for $i from 5 through 1 {
  .stack-#{$i} {
    z-index: $i * 10;
  }
}

Common Mistakes

  • Confusing through (inclusive) and to (exclusive), producing one fewer or one more rule than intended.
  • Using @for when the values to iterate aren't actually a numeric range, @each over a list or map is usually clearer in that case.
  • Generating an excessively large range that bloats the compiled CSS with rules that will never be used.
  • Forgetting that the loop variable only exists inside the loop's block, and trying to reference it afterward.

Key Takeaways

  • @for repeats a block a fixed number of times, counting through a numeric range.
  • through includes the end value; to stops one short of it.
  • @for is ideal for generating numbered grid columns, spacing scales, or z-index stacks.
  • The loop can count upward or downward depending on the start and end values given.

Pro Tip

Only generate as many steps as your project actually needs, a 12-step spacing scale sounds thorough but often produces far more unused utility classes than a carefully chosen 6-8 step scale mapped to real design decisions.