4 Topics
Chapter•110 Minutes

Sass Maps, Loops, and Conditional Logic

Use maps, @each, @for, @while, and @if to generate utility classes, manage design tokens, and build data-driven stylesheet patterns.

Maps and Structured Design Tokens

A Sass map stores key-value pairs. Maps are useful for color palettes, spacing scales, typography levels, breakpoints, and component variants.

The sass:map module provides functions for retrieving values, checking keys, and producing updated maps. A map centralizes related data and makes repetitive generation possible.

Maps are especially valuable when a design system has several named variants. Instead of scattering individual values across multiple files, define a structured map and consume it through functions, mixins, or loops.

Map keys should be descriptive and stable. Treat changes to public token names as API changes when other components depend on them.

Define a Spacing Map
@use "sass:map";

$spacing: (
  xs: 0.25rem,
  sm: 0.5rem,
  md: 1rem,
  lg: 1.5rem,
  xl: 2rem
);

.card {
  padding: map.get($spacing, md);
}

.section {
  margin-block: map.get($spacing, xl);
}
💡 The $spacing map stores named spacing tokens. map.get() retrieves the value associated with a key. Centralized maps reduce duplication and make it easier to review a design system's approved values. When a token is missing, consider adding explicit validation instead of silently producing incomplete CSS.
Knowledge Check

Which Sass built-in module should you use to retrieve a value from a map?

Generate Styles with @each

The @each directive iterates over a list or map. It is ideal for generating classes from named tokens because each iteration exposes a value or a key-value pair.

For a map of button variants, a loop can generate a class for every supported variant. For a spacing map, a loop can generate utilities for approved spacing tokens.

Generated utilities should be intentionally scoped. A loop that creates hundreds of selectors may produce unnecessary CSS if only a few classes are used. Consider whether a small set of reusable component styles would be more appropriate.

Generate Button Variants
$button-colors: (
  primary: #5b5bd6,
  success: #218838,
  danger: #c62828
);

@each $name, $color in $button-colors {
  .button--#{$name} {
    background-color: $color;
    color: white;
  }
}
💡 The loop iterates through each map entry. Interpolation inserts the key into the selector, and the corresponding color becomes the background value. The resulting stylesheet contains .button--primary, .button--success, and .button--danger.
Knowledge Check

Which directive is the natural choice for iterating through a map of named button variants?

Generate Repeated Utilities with @for

The @for directive iterates across a numeric range. It is useful when the generated selectors follow a predictable numeric pattern, such as a limited spacing scale or grid span utilities.

Sass supports through and to range syntax. through includes the ending number, whereas to stops before it.

For example, @for $i from 1 through 4 executes four iterations, while @for $i from 1 to 4 executes three.

Choose the smallest useful range. Large generated utility systems can increase CSS output and make class naming conventions harder to manage.

Generate Column Span Utilities
@for $i from 1 through 4 {
  .grid-span-#{$i} {
    grid-column: span $i;
  }
}
💡 The loop generates four selectors: .grid-span-1, .grid-span-2, .grid-span-3, and .grid-span-4. The generated declarations use CSS Grid's grid-column property. Ensure that the generated span values are meaningful within the grid layouts used by your application.
Knowledge Check

How many iterations occur in `@for $i from 1 through 4`?

Conditional Logic with @if, @else, and @while

Sass supports conditional compilation through @if, @else if, and @else. These directives can select which declarations or rules are emitted based on Sass values.

The @while directive repeats a block while a condition remains true. Although useful in some algorithms, it is generally less readable than @each or @for for ordinary stylesheet generation.

Conditions are evaluated during compilation. They cannot respond directly to a user's browser interaction or a CSS custom property's runtime value.

Keep conditional stylesheet generation deterministic. Complicated conditional trees can make the final CSS difficult to reason about, especially when several conditions generate overlapping selectors.

Validate public Sass APIs

Use @error for invalid configuration and @warn when an input is allowed but potentially problematic. These messages help catch design-system mistakes early.

Conditionally Generate a Theme
@mixin surface-theme($theme) {
  @if $theme == dark {
    background: #171717;
    color: #f5f5f5;
  } @else if $theme == light {
    background: #ffffff;
    color: #222222;
  } @else {
    @error "Unsupported theme: #{$theme}";
  }
}

.panel {
  @include surface-theme(dark);
}
💡 The mixin checks its argument and emits the matching declarations. If an unsupported theme is supplied, @error stops compilation with a useful message. Explicit validation is preferable to silently generating incorrect output when a function or mixin accepts a restricted set of values.
Knowledge Check

When does Sass evaluate an `@if` condition?