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.
You now understand how the @for loop generates a fixed number of repeated rules. Next, learn the @each loop for iterating over lists and maps.