Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Maps and the sass:map module

A map is a set of key–value pairs, like an object in JavaScript. Instead of five separate variables $breakpoint-sm, $breakpoint-md… you keep one map $breakpoints and ask it for a value by name. The sass:map module reads and changes maps.

Creating a map

A map is written in parentheses: key, colon, value, pairs separated by commas. Add the breakpoints to styles/abstracts/_variables.scss:

// styles/abstracts/_variables.scss
$breakpoints: (
  "sm": 576px,
  "md": 768px,
  "lg": 1024px,
);

Keys are usually quoted strings; a trailing comma after the last pair is allowed. A map is not a CSS value: you cannot write it into a property directly, only read values from it.

Reading a value

map.get() returns the value of a key:

// styles/main.scss
@use "sass:map";
@use "abstracts/variables";
 
.container {
  max-width: map.get(variables.$breakpoints, "lg");
}
.container {
  max-width: 1024px;
}

If the key does not exist, map.get() returns null, and a property with a null value is simply not printed.

A breakpoint mixin with names

Now the mixin from the lesson about @content can take a name instead of a width. Add it to styles/abstracts/_mixins.scss:

// styles/abstracts/_mixins.scss
@use "sass:map";
@use "variables";
 
@mixin from($name) {
  @media (min-width: map.get(variables.$breakpoints, $name)) {
    @content;
  }
}
// styles/components/_cards.scss
@use "../abstracts/mixins";
 
.cards {
  display: grid;
 
  @include mixins.from("md") {
    grid-template-columns: 1fr 1fr;
  }
}
// styles/main.scss
@use "components/cards";
.cards {
  display: grid;
}
@media (min-width: 768px) {
  .cards {
    grid-template-columns: 1fr 1fr;
  }
}

All breakpoints of the site now live in one map: to change "md", you edit one line.

Other functions of sass:map

FunctionWhat it does
map.has-key($map, $key)true if the key exists
map.keys($map)A list of all keys
map.values($map)A list of all values
map.merge($map1, $map2)A new map with the pairs of both; the second wins on repeats
map.remove($map, $key)A new map without the key
map.set($map, $key, $value)A new map with one key added or replaced

map.merge() is handy for adding keys to a map from a library:

// styles/main.scss
@use "sass:map";
 
$breakpoints: ("sm": 576px, "md": 768px);
$breakpoints: map.merge($breakpoints, ("xl": 1280px));
 
.wide {
  max-width: map.get($breakpoints, "xl");
}
.wide {
  max-width: 1280px;
}

Nested maps

A value in a map can itself be a map. map.get() then takes several keys in a row:

// styles/main.scss
@use "sass:map";
 
$theme: (
  "button": ("bg": #2563eb, "text": white),
);
 
.btn {
  color: map.get($theme, "button", "text");
  background: map.get($theme, "button", "bg");
}
.btn {
  color: white;
  background: #2563eb;
}

Nested maps are the basis for design tokens and themes later in the course.

Common mistake

A typo in a key gives no error: map.get($breakpoints, "medium") returns null, the mixin compiles to @media (min-width: ), and the browser silently ignores this broken query. Check keys with map.has-key() and stop the build with @error — the lesson about debug messages shows how.

Thanks for reading!

Donate to the site — we work hard for you.