Skip to content

The Sass @each Loop

The @each loop is the most frequently used Sass control rule in real projects, iterating over lists and maps to generate CSS from design tokens. This lesson covers @each syntax for lists, maps, and multiple values at once.

How the @each Loop Works

@each iterates over every item in a list, or every key-value pair in a map, running its block once per item with loop variables bound to the current value (or key and value, for maps).

$sizes: sm, md, lg;

@each $size in $sizes {
  .text-#{$size} {
    font-size: var(--font-#{$size});
  }
}

This generates .text-sm, .text-md, and .text-lg, each referencing a matching CSS custom property.

@each Syntax Forms

@each $item in $list { ... }
@each $key, $value in $map { ... }
@each $a, $b in $list-of-lists { ... }
  • @each $item in $list binds a single variable to each list item in turn.
  • @each $key, $value in $map destructures each map entry into two variables.
  • @each can also destructure a list of same-length sub-lists into multiple variables per iteration.
  • The loop runs once per item, in the order the list or map was defined.

@each Loop Cheatsheet

Common @each patterns for design tokens and utility generation.

Pattern Example Use Case
Simple list @each $c in (red, green, blue) Loop over a flat list of values
Map entries @each $k, $v in (sm: 8px, md: 16px) Generate a rule per named token
Nested list pairs @each $name, $hex in $color-pairs Destructure list-of-lists data
Color palette @each $name, $color in $colors Generate color utility classes
Breakpoints @each $name, $width in $breakpoints Generate responsive utility classes

Iterating a Simple List

The simplest form of @each loops over a flat list, binding one variable per item, useful for generating a set of related utility classes from a short list of keywords.

$directions: top, right, bottom, left;

@each $direction in $directions {
  .border-#{$direction} {
    border-#{$direction}: 1px solid #cbd5e1;
  }
}

Iterating a Map

Iterating a map is by far the most common real-world use of @each, generating one CSS rule per design token (spacing value, color, breakpoint) defined in a central map.

$spacers: (
  0: 0,
  1: 0.25rem,
  2: 0.5rem,
  3: 1rem,
);

@each $key, $value in $spacers {
  .p-#{$key} {
    padding: $value;
  }
}

@each With Nested Lists

When each "row" of data has more than two related values, a list of small lists (or lists of maps) can be destructured with multiple loop variables in a single @each statement.

$icons: (home, "\\e901"), (search, "\\e902"), (user, "\\e903");

@each $name, $glyph in $icons {
  .icon-#{$name}::before {
    content: $glyph;
  }
}

Common Mistakes

  • Using @for with manual list.nth() lookups instead of the far more readable @each for simple list iteration.
  • Forgetting the comma between $key, $value when destructuring a map, which causes a syntax error.
  • Iterating over a map assuming a specific key order across all environments; while Dart Sass preserves insertion order, don't rely on order for values where correctness matters more broadly.
  • Not handling a possible null value gracefully when a map entry is intentionally left blank.

Key Takeaways

  • @each iterates over lists and maps, and is the most commonly used Sass control rule in real projects.
  • Map iteration destructures each entry into a key and value variable in one statement.
  • Nested lists can be destructured into multiple loop variables per iteration.
  • @each over design-token maps is the standard way to generate consistent utility classes.

Pro Tip

Whenever you catch yourself reaching for @for with list.nth() to pull related data out by index, refactor to a map and use @each $key, $value in $map instead, it's virtually always more readable and less error-prone.