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

@each

@each iterates over a list or map. Use it to generate utility classes, theme tokens, and per-variant rules from a single data definition. Combined with @use and modules, it lets a 20-line map produce hundreds of consistent CSS rules.

Generate utilities and component variants from maps

EXAMPLE
@use 'sass:map';

// 1) @each over a map of tokens -> spacing utilities
$space: (
  'xs': .25rem,
  'sm': .5rem,
  'md': 1rem,
  'lg': 2rem,
  'xl': 4rem,
);

@each $name, $value in $space {
  .p-#{$name}    { padding: $value; }
  .px-#{$name}   { padding-inline: $value; }
  .py-#{$name}   { padding-block: $value; }
  .m-#{$name}    { margin: $value; }
  .mx-#{$name}   { margin-inline: $value; }
  .my-#{$name}   { margin-block: $value; }
  .gap-#{$name}  { gap: $value; }
}

// 2) @each over a nested map -> button variants
$buttons: (
  'primary':   ('bg': #2563eb, 'fg': white),
  'secondary': ('bg': #e2e8f0, 'fg': #0f172a),
  'danger':    ('bg': #dc2626, 'fg': white),
  'ghost':     ('bg': transparent, 'fg': #2563eb),
);

@each $name, $colors in $buttons {
  .btn-#{$name} {
    background: map.get($colors, 'bg');
    color:      map.get($colors, 'fg');
    padding: .5rem 1rem;
    border-radius: 6px;
    transition: background .15s ease;
    &:hover { background: darken(map.get($colors, 'bg'), 8%); }
  }
}

// 3) @each over a list (no keys, just values)
$priorities: 'low', 'medium', 'high', 'urgent';
$priority-colors: ('low': #64748b, 'medium': #2563eb, 'high': #f59e0b, 'urgent': #dc2626);

@each $p in $priorities {
  .priority-#{$p} {
    color: map.get($priority-colors, $p);
  }
}

// 4) Generate responsive utilities
$breakpoints: ('sm': 480px, 'md': 768px, 'lg': 1024px, 'xl': 1280px);

@each $bp-name, $bp-value in $breakpoints {
  @media (min-width: $bp-value) {
    @each $name, $value in $space {
      .#{$bp-name}\:p-#{$name}  { padding: $value; }
      .#{$bp-name}\:m-#{$name}  { margin: $value; }
    }
  }
}

// Now .md\:p-md applies at min-width: 768px.

// 5) Generate colour palettes
$colors: (
  'blue':  (50: #eff6ff, 500: #2563eb, 900: #1e3a8a),
  'red':   (50: #fef2f2, 500: #dc2626, 900: #7f1d1d),
  'gray':  (50: #f8fafc, 500: #64748b, 900: #0f172a),
);

@each $color, $shades in $colors {
  @each $shade, $value in $shades {
    .text-#{$color}-#{$shade}     { color: $value; }
    .bg-#{$color}-#{$shade}       { background-color: $value; }
    .border-#{$color}-#{$shade}   { border-color: $value; }
  }
}

// 6) Iterate map with multiple values
$social: (
  'twitter':   (color: #1da1f2, url: 'https://twitter.com'),
  'github':    (color: #181717, url: 'https://github.com'),
  'linkedin':  (color: #0a66c2, url: 'https://linkedin.com'),
);

@each $name, $info in $social {
  .social-#{$name} {
    color: map.get($info, color);
    &:hover { color: lighten(map.get($info, color), 10%); }
    &::after { content: ' (' + map.get($info, url) + ')'; }
  }
}

// 7) Combine with @for for indexed iteration
$grid-cols: 12;
@for $i from 1 through $grid-cols {
  .col-#{$i} { grid-column: span $i; }
}

// 8) Patterns to internalise
// - Map = source of truth for design tokens
// - @each generates the CSS from the map; one place to update
// - Nest @each loops to cross-product (breakpoint x spacing)
// - Avoid generating thousands of unused rules; tree-shake with purgecss/tailwindcss
// - Use #{} for interpolation in selector names

// 9) Pitfalls
// - Generating massive CSS from huge maps -> bundle bloat
// - Forgetting @use 'sass:map' before map.get
// - Spaces inside #{} sometimes leak into selectors
// - Treating maps as ordered (they are, but rely on declaration order, not key sort)

Why it matters

A single SCSS map of tokens + an @each loop generates the consistent CSS your design system needs. The map IS the design system; the loop is the implementation. Change the token; the entire codebase updates — no find-and-replace, no drift between Figma and code.

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

Example

Example
@each $name, $color in (primary #04AA6D, danger #c00) {
    .text-\#{$name} { color: $color; }
}
Try it Yourself »

Exercise

Loop over a list.

$color in red, green, blue { /* … */ }

Discussion

Loading…