iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

@while

@while loops in Sass: generate repetitive CSS, build grid systems, and stamp out variant classes when @each will not do.

Sass — @while

EXAMPLE
// ===== Basic @while =====
// Generate a set of spacing utility classes:
$i: 0;
@while $i <= 10 {
  .mt-#{$i} { margin-top: #{$i * 0.25}rem; }
  $i: $i + 1;
}
// Compiles to .mt-0 { margin-top: 0; } ... .mt-10 { margin-top: 2.5rem; }

// ===== When @while wins =====
// - Loop with a condition that is not a simple range
// - Build sequences where the step depends on the value
// - Stop when a property hits a threshold

@use 'sass:math';

@function fibonacci($n) {
  $a: 0;
  $b: 1;
  @while $n > 0 {
    $tmp: $a + $b;
    $a: $b;
    $b: $tmp;
    $n: $n - 1;
  }
  @return $a;
}

.fib-5 { width: #{fibonacci(5)}px; }   // 5

// ===== @while for grid systems =====
$cols: 12;
$i: 1;
@while $i <= $cols {
  .col-#{$i} { width: math.div($i, $cols) * 100%; }
  $i: $i + 1;
}
// .col-1 { width: 8.333%; } ... .col-12 { width: 100%; }

// ===== @while vs @for vs @each =====
// @for $i from 1 through 10        for known ranges (preferred when possible)
// @each $name in (a, b, c)         for explicit lists
// @while ...                      for everything else

// ===== Bail-out conditions =====
// Always increment the loop variable; otherwise infinite loop.
// Sass compilers detect runaway loops and abort, but only after burning cycles.

// ===== Pitfalls =====
// - Forgetting $i: $i + 1 -> infinite loop
// - Heavy @while in production -> long compile times
// - Generating thousands of selectors that purge later wastes both build + parse time
// - Preferring @while when @for / @each would read better

// ===== Patterns to internalise =====
// - @for over @while when the bounds are known
// - @while only for variable-step or condition-based loops
// - Generate purgeable utility classes; pair with a purge step or Tailwind
// - Output the smallest necessary CSS; selectors are not free

// ===== A combined example: typographic scale =====
$base-size: 1rem;
$ratio: 1.25;     // Major third
$max-step: 6;

@function scale($step) {
  $val: $base-size;
  $i: 0;
  @while $i < $step {
    $val: $val * $ratio;
    $i: $i + 1;
  }
  @return $val;
}

.text-base { font-size: $base-size; }
.text-lg   { font-size: scale(1); }
.text-xl   { font-size: scale(2); }
.text-2xl  { font-size: scale(3); }
.text-3xl  { font-size: scale(4); }

Why it matters

@while fills the niche between @for(known ranges) and @each(explicit lists): loops with a condition or variable step. Use it sparingly; prefer @for / @each when they fit. The wins are computed typographic scales, grid systems, and the rare numeric algorithm that needs a stop condition.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
$i: 1;
@while $i <= 5 {
    .item-\#{$i} { opacity: $i * 0.1; }
    $i: $i + 1;
}
Try it Yourself »

Discussion

Loading…