Skip to content

Sass Control Rules

Control rules bring real programming logic, conditionals and loops, into your stylesheets. This lesson gives a practical overview of every control rule Sass supports before the following lessons dive into each one individually.

What Are Sass Control Rules?

Sass has four control rules: @if/@else for conditionals, @for for counting loops, @each for iterating over lists and maps, and @while for open-ended looping based on a condition. Together they let you generate repetitive CSS patterns programmatically instead of writing them by hand.

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

This single @for loop generates three separate CSS rules, .col-1, .col-2, and .col-3, without repeating the pattern by hand.

Control Rules at a Glance

@if condition { ... } @else { ... }
@for $i from start through end { ... }
@each $item in $list { ... }
@while condition { ... }
  • @if/@else branches based on a boolean condition.
  • @for repeats a block a fixed number of times, with through (inclusive) or to (exclusive) of the end value.
  • @each iterates over a list, map, or multiple lists at once.
  • @while repeats a block as long as a condition stays true; the least common of the four, since @for/@each usually cover the same needs more safely.

Control Rules Cheatsheet

Choosing the right control rule for a given task.

Rule Best For Example
@if / @else Branching based on a condition @if $dark { ... }
@for A fixed, known number of repetitions @for $i from 1 through 12
@each Iterating list or map items @each $c in $colors
@while Looping until a condition becomes false @while $i > 0

When to Use Each Control Rule

Most real-world Sass logic uses @each for looping over design tokens (colors, spacers, breakpoints), and @if/@else for conditional output inside mixins and functions. @for shows up for generating numbered utility classes (like a 12-column grid), and @while is rare in modern, well-structured Sass.

  • Iterating a map of colors or spacers → @each.
  • Generating a fixed range of numbered classes (.col-1 through .col-12) → @for.
  • Branching mixin behavior based on a parameter → @if/@else.
  • Looping until a dynamic condition is met (rare) → @while.

Combining Control Rules

Control rules can nest inside each other, a common pattern combines @each (to loop over breakpoints) with @if (to skip generating a base, unprefixed rule for the smallest breakpoint).

$breakpoints: (sm: 576px, md: 768px, lg: 992px);

@each $name, $width in $breakpoints {
  @if $name != sm {
    @media (min-width: $width) {
      .hide-#{$name} {
        display: none;
      }
    }
  }
}

Control Rules and Output CSS Size

Loops are compile-time only, but they can still generate a large amount of compiled CSS if used carelessly. Always sanity-check the compiled output of a loop-heavy file, especially when generating utility classes across many breakpoints or color variants.

Common Mistakes

  • Reaching for @while when @for or @each would express the same logic more safely and clearly.
  • Writing deeply nested loops that generate an unexpectedly large amount of compiled CSS.
  • Forgetting that control rules run entirely at compile time; they cannot react to anything happening in the browser at runtime.
  • Not testing the actual compiled CSS output of a loop, only checking that the SCSS compiles without error.

Key Takeaways

  • Sass has four control rules: @if/@else, @for, @each, and @while.
  • @each is the most common, used heavily with maps and lists of design tokens.
  • @for suits fixed-count repetition; @while suits rare, dynamic-condition looping.
  • All control rules execute at compile time and directly affect the size of your compiled CSS.

Pro Tip

Before shipping a loop-heavy Sass file, run the compiler and actually read the generated CSS output at least once, it's the best way to catch unexpectedly large or duplicated output before it reaches production.