Sass @for Rule

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
Numeric ranges

What You’ll Learn

Sass @for counts from one number to another and runs a block for each step. This page covers through vs to, counting up or down, utility scales, grids, and five compiled examples.

01

Loop

@for

02

Through

End included

03

To

End excluded

04

Direction

Up or down

05

Generate

Scales & grids

06

Practice

5 examples

What Is @for?

Official docs: the @for rule counts up or down from one number to another and evaluates a block for each number in between. Each number along the way is assigned to the variable you name.

Write it as @for <variable> from <start> through <end> { … } or @for <variable> from <start> to <end> { … }.

  • Compile-time only—browsers never see @for.
  • Ideal when you need a numeric series (1…n columns, spacing steps, z-index layers).
  • through includes the end; to excludes it.
  • Use interpolation (#{$i}) to build selectors and values.
💡
Beginner tip

Think of @for as “count from A to B and write these styles each time.” Prefer @each when you already have named tokens in a list or map.

📝 Syntax

styles.scss
@for $i from 1 through 3 {
  .step-#{$i} {
    order: $i;
  }
}

⚖️ through vs to

Official docs: if to is used, the final number is excluded; if through is used, it is included.

FormRange for 1 … 3
from 1 through 31, 2, 3 (end included)
from 1 to 31, 2 (end excluded)
💡
Fun fact

from 0 to $count is a handy zero-based pattern: you get 0$count - 1—perfect for stacking $count items.

🔄 Counting Up or Down

If the start is smaller than the end, Sass counts upward. If the start is larger, it counts downward. The same through / to rules still apply.

styles.scss
@for $i from 5 through 1 {
  .layer-#{$i} {
    z-index: $i;
  }
}

⚖️ @for vs @each

NeedPrefer
Count 1…n or a numeric range@for
Walk known values / tokens@each
Key/value design tokens@each $k, $v in $map

⚡ Quick Reference

GoalCode
Inclusive range@for $i from 1 through 4 { … }
Exclusive end@for $i from 1 to 4 { … }
Count downward@for $i from 5 through 1 { … }
Build a class.col-#{$i} { … }
Zero-based stack@for $i from 0 to $count { … }

Examples Gallery

Each example generates multiple CSS rules from one numeric loop. Open View Compiled CSS for verified output.

📚 Getting Started

Count a range and emit related CSS rules.

Example 1 — :nth-child Color Steps

Official-docs style: lighten a base color for each index in the range.

styles.scss
@use "sass:color";

$base-color: #036;

@for $i from 1 through 3 {
  ul:nth-child(3n + #{$i}) {
    background-color: color.adjust($base-color, $lightness: $i * 5%);
  }
}

How It Works

$i becomes 1, then 2, then 3. Interpolation builds the selector; sass:color adjusts lightness each pass (modern alternative to deprecated lighten()).

Example 2 — through vs to Side by Side

Four-column widths with through; flex grow steps with to.

styles.scss
@use "sass:math";

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

@for $i from 1 to 4 {
  .span-#{$i} {
    flex-grow: $i;
  }
}

How It Works

through 4 emits .col-1.col-4. to 4 stops before 4, so you only get .span-1.span-3.

📈 Scales, Layers & Stacks

Countdown, spacing utilities, and zero-based positioning.

Example 3 — Count Down for Z-Index Layers

Start high and walk down to emit stacking classes in reverse order.

styles.scss
@for $i from 5 through 1 {
  .layer-#{$i} {
    z-index: $i;
  }
}

How It Works

Because 5 is greater than 1, Sass counts downward: 5, 4, 3, 2, 1.

Example 4 — Spacing Utility Scale

Generate margin and padding steps from 0 through 5.

styles.scss
@for $i from 0 through 5 {
  .mt-#{$i} {
    margin-top: $i * 0.25rem;
  }

  .p-#{$i} {
    padding: $i * 0.25rem;
  }
}

How It Works

One loop writes two utility families. Change the step (0.25rem) once to rescale the whole system.

Example 5 — Zero-Based Item Stack Mixin

Use from 0 to $count to position $count stacked items.

styles.scss
@mixin order-stack($count, $height: 40px) {
  @for $i from 0 to $count {
    .item-#{$i + 1} {
      position: absolute;
      top: $i * $height;
      height: $height;
    }
  }
}

@include order-stack(3, 50px);

How It Works

from 0 to 3 yields 0, 1, 2. Class names use $i + 1 so humans see .item-1.item-3, while offsets stay zero-based.

🚀 Real-World Use Cases

  • Grid columns.col-1.col-12 widths.
  • Spacing scales — margin / padding utilities from a numeric step.
  • Z-index layers — countdown or ascending stacking classes.
  • Nth patterns — striped lists, staggered animations, hue steps.
  • Mixin parameters — generate N items from a $count argument.

🧠 How Compilation Works

1

Resolve the range

Evaluate start and end numbers; pick up or down.

Bounds
2

Assign the counter

Set your variable (for example $i) to the current number.

Bind
3

Evaluate the block

Emit CSS for this step, then move to the next number.

Repeat
4

CSS ships

All generated rules appear; @for itself does not.

⚠️ Common Pitfalls

  • Confusing to with through — off-by-one bugs are the classic mistake.
  • Huge CSS output@for $i from 1 through 1000 can explode file size.
  • Using @for for named tokens — prefer @each for lists and maps.
  • Forgetting interpolation — selectors need #{$i}, not bare $i.
  • Non-integer ranges — keep ends as whole numbers unless you intentionally need fractional steps.

💡 Best Practices

✅ Do

  • Choose through or to deliberately for inclusive vs exclusive ends
  • Name the counter clearly ($i, $col, $step)
  • Drive ranges from variables ($columns, $steps)
  • Combine with mixins when the recipe is reusable
  • Generate only the steps your design system needs

❌ Don’t

  • Hand-copy nearly identical numbered rules when a loop would do
  • Loop unbounded ranges into production CSS
  • Use @for when you already have a token list—use @each
  • Forget that to excludes the end value
  • Nest enormous loops without checking output size

Key Takeaways

Knowledge Unlocked

Five things to remember about Sass @for

Count numeric ranges at compile time to generate repetitive CSS cleanly.

5
Core concepts
02

through

end included

Inclusive
🚫 03

to

end excluded

Exclusive
🔄 04

Direction

up or down

Order
05

Compile

many CSS rules

Output

❓ 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.
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).
Did you know?

Official Sass docs show @for with :nth-child selectors and color steps—a classic pattern for striped or staggered list styling without hand-writing each rule.

Conclusion

@for is the go-to control rule when you need to count through a numeric range. Use through to include the end, to to exclude it, and count up or down as needed for scales, grids, and stacked layouts.

Continue with @while or the Sass introduction.

Next: Sass @while Rule

Loop while a condition stays true—and know when to prefer @for/@each.

Sass @while Rule →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful