The Sass @for rule counts from one number to another and evaluates a block once per number. Each number is assigned to a variable you name.
Write @for $i from <start> through <end> { … } to include the end, or from <start> to <end> to exclude it. Sass counts up or down. Prefer @for when you need a numeric range; prefer @each when you already have a list or map of values.
Official pattern.
Per the Sass docs: through includes the final number; to excludes it. Use interpolation (#{$i}) to build selectors.
Compile-time only.
Browsers never see @for — only the CSS generated for each iteration.
Deprecated global lighten().
Official samples sometimes show lighten(). Prefer @use "sass:color" and color.adjust(…, $lightness: …) in modern Dart Sass.
Most @for bugs are through vs to, huge ranges, or choosing the wrong loop.
through
through includes the end
from 1 through 3 runs three times. from 1 to 3 runs twice. Off-by-one bugs usually start here.
output
Large ranges grow CSS fast
Every iteration emits real CSS. Keep utility scales intentional for production builds.
each
Have values already? Use @each
If you own a list or map of tokens, @each is clearer than inventing indexes with @for.
units
Ends must be numbers
Start and end expressions must resolve to numbers. Compatible units are fine; mixed incompatible units fail at compile time.
Toolchain
Sass Support
@for is a core Dart Sass control rule. It is not a browser CSS feature — support means your Sass compiler understands it.
Implementation
Status
Dart Sass
Supported (recommended)
LibSass / node-sass
Supported (deprecated toolchain)
Ruby Sass
Supported (end-of-life)
Browsers
N/A — only see compiled CSS
Prefer Dart Sass for new projects. SCSS and indented syntax both support @for.
Remember
Key Takeaways
Count:@for $i from … assigns each number to $i.
through includes the end; to excludes it.
Direction: start > end counts down automatically.
Have tokens? Prefer @each over inventing indexes.
One line:@for walks a numeric range and emits CSS once per number.
Compile
Compile Notes
@for never reaches the browser. Conceptual flow:
flow.txt
1. Evaluate start and end numbers
2. Decide direction (up if start ≤ end, else down)
3. Include or exclude the end (through vs to)
4. Bind $i, evaluate the block, emit CSS
5. Step to the next number until the range ends
Frequently Asked Questions
It counts from one number to another and evaluates a block once per number, assigning that number to a variable you name. The loop runs at compile time.
through includes the end number. to excludes it. So from 1 through 3 runs 1, 2, 3; from 1 to 3 runs 1, 2.
Yes. If the start is greater than the end (for example from 5 through 1), Sass counts down.
No. @for is compile-time only. Browsers see the styles generated for each iteration.
@for walks a numeric range. @each walks values in a list or map. Use @for when you need to count; use @each when you already have the items.
Yes. Both ends can be any Sass expressions that resolve to numbers (including variables and math).