Skip to content
Glasspage.studio

What is a design token, and how is it different from a CSS variable?

A design token names a design decision (surface-raised, text-muted); a CSS variable is just the storage slot that holds its value — so any token named after its value, like grey-100 or blue-500, is a CSS variable wearing a token's name and will break at the first rebrand.

By Ethan Hibble

The definition, and the one-line test

A design token is a named design decision. A CSS variable is a named value. In practice a token is usually implemented as a CSS custom property, which is why the two get conflated — but the custom property is the delivery mechanism, not the thing itself. The token is the agreement that quiet body text on a card uses this particular colour, and that the agreement holds everywhere.

The test is the name. Read the token’s name and ask what it tells you. If it tells you the value — grey-100, blue-500, spacing-16, font-14 — it is a variable in costume. If it tells you the decision — text-muted, surface-raised, space-section, text-body — it is a token. Nothing about the CSS changes; everything about what happens next does.

Why it matters is rebrand day. A site built on grey-100 requires you to find every use of grey-100 and judge, one by one, whether that particular use meant a border, a disabled label, or a card background — because the name recorded none of that. A site built on border-subtle, text-disabled and surface-sunken requires you to change three values. We have done both kinds of change. The first is a week of archaeology, the second is an afternoon.

  • Variable in costume: --blue-500, --grey-100, --radius-8, --font-14
  • Token: --accent, --border-subtle, --radius-control, --text-body
  • The difference is not syntax. Both are custom properties. Only one survives a change of mind.

The two naming layers we actually ship

Every Glasspage redesign ships two layers, and only the second is a token. The first is the palette: the raw values, named after what they are, because that is honest — a hex code, a step on a type scale, a number on a spacing ramp. Nothing in a component ever references this layer directly.

The second layer is the semantic layer, and it is the only one components are allowed to touch. Those names describe roles: page background, raised surface, primary text, muted text, subtle border, accent, focus ring, control radius, section spacing. Each one points at a palette value. When a client’s brand colour changes, the palette entry changes and every semantic token that references it updates with it, which is the whole point of keeping the layers separate.

We stop at two. A third layer of component-scoped tokens — button-primary-background-hover, card-header-padding-compact — is where generated token sets balloon into the hundreds, and on a site of thirty or forty pages it buys nothing. If exactly one component uses a value, that value belongs in the component, not in the system. A token earns its place by being used in more than one place by more than one person.

Why we hand over about 40 tokens, not 400

A typical Glasspage handover contains roughly 40 semantic tokens: around a dozen colour roles, six or seven spacing steps, five or six type sizes, two or three radii, two shadows, a couple of border widths, and a small set for motion durations and easing. That is the whole vocabulary of the site.

The number is deliberate. A token set is a language, and a language nobody can hold in their head stops being used — the developer who cannot remember whether it is surface-elevated-2 or surface-raised-alt just writes a hex code, and the system quietly dies while the documentation says it is alive. Forty is small enough that the person maintaining your site after us can read the list in one sitting.

Automated exports from design tools routinely produce several hundred tokens because they export every value that appears in the file, including the ones that appear once by accident. That is a dump of the design, not a system. The editing work — deciding which values are decisions and which are one-offs, then giving the decisions role names — is what turns the dump into something a team can use, and it is the part a generator cannot do for you.

Related articles