Design tokens in maps
Design tokens are the named basic values of a design: colours, spacing steps, font sizes, radii. Designers and developers agree on the names — primary, space 2, radius md — and the code uses only these names, never random values. In Sass tokens are naturally stored in maps.
A tokens file
Create styles/abstracts/_tokens.scss with three groups of tokens:
// styles/abstracts/_tokens.scss
$colors: (
"primary": #2563eb,
"surface": #ffffff,
"text": #1f2937,
"muted": #6b7280,
);
$space: (
1: 4px,
2: 8px,
3: 16px,
4: 32px,
);
$radius: (
"sm": 4px,
"md": 8px,
);The spacing keys are numbers: 1, 2, 3. Number keys are written without quotes.
Functions for reading tokens
Writing map.get(tokens.$colors, "primary") every time is long. Small functions make it short and check the name. Create styles/abstracts/_functions.scss:
// styles/abstracts/_functions.scss
@use "sass:map";
@use "tokens";
@function color($name) {
@if not map.has-key(tokens.$colors, $name) {
@error "Unknown colour token '#{$name}'.";
}
@return map.get(tokens.$colors, $name);
}
@function space($step) {
@return map.get(tokens.$space, $step);
}
@function radius($name) {
@return map.get(tokens.$radius, $name);
}Using tokens in a component
The card takes all its values from tokens:
// styles/components/_cards.scss
@use "../abstracts/functions" as fn;
.card {
padding: fn.space(3);
color: fn.color("text");
background: fn.color("surface");
border: 1px solid fn.color("muted");
border-radius: fn.radius("md");
}// styles/main.scss
@use "components/cards";.card {
padding: 16px;
color: #1f2937;
background: #ffffff;
border: 1px solid #6b7280;
border-radius: 8px;
}<style>
.card {
padding: 16px;
color: #1f2937;
background: #ffffff;
border: 1px solid #6b7280;
border-radius: 8px;
}
</style>
<div class="card">The card's values come from tokens</div>If the designer changes space 3 from 16px to 20px, you edit one line in _tokens.scss, and every card, form and header updates.
Generating classes from tokens
The same maps feed utility classes, so the classes always match the tokens:
// styles/utilities/_spacing.scss
@use "../abstracts/tokens";
@each $step, $value in tokens.$space {
.p-#{$step} {
padding: $value;
}
}// styles/main.scss
@use "utilities/spacing";.p-1 {
padding: 4px;
}
.p-2 {
padding: 8px;
}
.p-3 {
padding: 16px;
}
.p-4 {
padding: 32px;
}Why not plain variables
| Separate variables | Tokens in a map |
|---|---|
$space-1, $space-2, $space-3 | One map $space |
| A loop over them is impossible | @each goes through all tokens |
A typo is an Undefined variable error | A typo is caught by @error in the function |
| Easy for a small project | Scales to dozens of values |
Common mistake
Do not bypass the tokens "just this once" with a value like padding: 15px. One exception becomes ten, and the next design change misses them. If a value is missing, add a token for it — or ask whether the nearest existing step will do.