Design tokens have become standard practice in large design systems. They're named values — colors, sizes, spacing — that keep a design consistent across platforms. But for a website built with HTML and CSS, you don't need a separate token system. CSS custom properties do the job natively.
Defining your tokens
A fluid design system needs two sets of tokens: type steps and space values. Both use clamp() to scale between viewports.
:root {
--step-0: clamp(1rem, 0.9rem + 0.5vi, 1.25rem);
--step-1: clamp(1.2rem, 1.05rem + 0.73vi, 1.5625rem);
--space-s: clamp(1rem, 0.91rem + 0.43vi, 1.25rem);
--space-m: clamp(1.5rem, 1.37rem + 0.65vi, 1.875rem);
}
These properties are available everywhere in your CSS. You reference them just like any other value.
Why this works
CSS custom properties have some properties that make them ideal for design tokens:
- They cascade — set them on
:rootand they're available everywhere, or scope them to specific components - They're live — change a value and every element using it updates instantly
- They need no build step — no compilation, no preprocessing, no tooling
- They're inspectable — browser DevTools show you exactly what's happening
The naming convention
Utopia uses a simple, semantic naming pattern. Type steps are numbered from a baseline of 0, going up for headings and down for small text. Space values use t-shirt sizes. This keeps names meaningful without tying them to specific pixel values that would change across viewports.
One file, complete system
The entire design system fits in a single CSS file — a list of custom properties. Every other style in the project references these tokens. Want to adjust the scale? Change the values in one place. The consistency is structural, not just conventional.