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

Maps

Sass maps are key/value collections — ordered, immutable, and ideal for storing design tokens, breakpoints, theme palettes, anything you want to look up by name. The sass:map module gives you a clean API.

map.get, map.set, theming patterns

EXAMPLE
// 1) Declare a map
$colors: (
    'primary':   #4f46e5,
    'secondary': #14b8a6,
    'danger':    #ef4444,
    'warning':   #f59e0b,
    'success':   #22c55e,
);

$breakpoints: (
    'sm': 640px,
    'md': 768px,
    'lg': 1024px,
    'xl': 1280px,
);

// 2) Use the sass:map module (always @use, not @import)
@use 'sass:map';
@use 'sass:list';
@use 'sass:meta';

// 3) Read values
.btn-primary {
    background: map.get($colors, 'primary');
    color:      map.get($colors, 'primary');           // safe — returns null if missing
}

// 4) Insert / overwrite (returns a NEW map; Sass maps are immutable)
$colors: map.set($colors, 'accent', #ff8a00);
$colors: map.merge($colors, ('muted': #6b7280, 'border': #e5e7eb));

// 5) Loop over a map → @each
@each $name, $value in $colors {
    .text-#{$name}   { color: $value; }
    .bg-#{$name}     { background: $value; }
    .border-#{$name} { border-color: $value; }
}

// 6) Nested maps — theme system
$theme: (
    'light': (
        'bg':     #ffffff,
        'text':   #0f172a,
        'border': #e5e7eb,
    ),
    'dark':  (
        'bg':     #0f172a,
        'text':   #f1f5f9,
        'border': #1e293b,
    ),
);

@function token($mode, $key) {
    $mode-map: map.get($theme, $mode);
    @if not $mode-map { @error "Unknown theme mode '#{$mode}'"; }
    @return map.get($mode-map, $key);
}

:root {
    @each $key, $_ in map.get($theme, 'light') {
        --#{$key}: #{token('light', $key)};
    }
}
.dark {
    @each $key, $_ in map.get($theme, 'dark') {
        --#{$key}: #{token('dark', $key)};
    }
}

body {
    background: var(--bg);
    color:      var(--text);
}

// 7) Responsive breakpoints from a map
@mixin respond($name) {
    $value: map.get($breakpoints, $name);
    @if not $value { @error "Unknown breakpoint '#{$name}'"; }
    @media (min-width: #{$value}) { @content; }
}

.hero {
    padding: 2rem;
    @include respond('md') { padding: 4rem; }
    @include respond('lg') { padding: 6rem; }
}

// 8) Spacing scale
$space: (
    '0':  0,
    '1':  0.25rem,
    '2':  0.5rem,
    '3':  0.75rem,
    '4':  1rem,
    '6':  1.5rem,
    '8':  2rem,
    '12': 3rem,
);

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

// 9) Inspecting maps
.debug {
    keys:   map.keys($colors);          // ('primary', 'secondary', 'danger', …)
    values: map.values($colors);         // colors
    size:   list.length(map.keys($colors));
}

// 10) has-key — safe lookup
@function safe-color($name) {
    @if not map.has-key($colors, $name) {
        @warn "Color '#{$name}' missing — falling back to primary";
        @return map.get($colors, 'primary');
    }
    @return map.get($colors, $name);
}

// 11) Deep get — nested key path
@function deep-get($map, $keys...) {
    @each $key in $keys {
        $map: map.get($map, $key);
        @if $map == null { @return null; }
    }
    @return $map;
}

.dark-bg { background: deep-get($theme, 'dark', 'bg'); }

// 12) Module pattern — keep design tokens in one file
// _tokens.scss
@forward 'colors' as color-*;        // exposes color-$primary etc.

// 13) Common bugs
//   • Using @import — deprecated, all globals leak; use @use 'sass:map'
//   • Sass maps are IMMUTABLE — map.set returns a new map, doesn't mutate
//   • Trailing commas in some old parsers — modern Dart Sass allows them
//   • Forgetting #{$value} string interpolation in selectors and media queries
//   • Using map.get with a missing key — returns null silently; add @error or @warn for required keys

Why it matters

Maps are the cleanest way to store design tokens — spacing scales, breakpoints, theme palettes — and pair beautifully with @each for generating utility classes. Wrap map.get in a function that errors on missing keys; the build-time crash is far easier to fix than a silent null shipping to production.

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

Example

Example
$theme: (primary: #04AA6D, danger: #c00);
.btn { background: map-get($theme, primary); }
Try it Yourself »

Discussion

Loading…