Semantic colour tokens: naming colours by role so themes stay coherent
Semantic colour tokens name colours by what they do, not what they look like: surface, text-muted, action, danger. Components use only those names, and each name points at a raw colour. Change what action points to and every button updates; switch the whole set for dark mode and nothing needs redesigning.
Two layers: primitive vs semantic tokens
Most token systems separate two kinds of name. Primitive tokens (sometimes called base or palette tokens) describe the available colours: green-700, sand-100, grey-900. Semantic tokens describe jobs: action, surface, text. A semantic token's value is a reference to a primitive one. The Design Tokens Format Module, published by the W3C Design Tokens Community Group as a stable community report rather than a W3C standard, writes such a reference with curly braces, so action might hold {color.green.700}.
| Layer | Example name | Value | Who uses it |
|---|---|---|---|
| Primitive | green-700 | #1f6f43 | Only the semantic layer |
| Semantic | action | {green-700} | Buttons, links, focus rings |
| Component (optional) | button-bg | {action} | One component |
A third, component layer is common in large product systems, but small sites rarely need it. Every extra layer is another place a colour can be changed without anyone noticing what else moved.
Colour token naming by role
Good names describe intent and stay true whatever the colour becomes. blue-button breaks the day the brand turns green; action doesn't. A set that covers most sites:
- ground
- The page background.
- surface
- Cards, panels and alternate bands, one step from the ground.
- text
- Body text and headings.
- text-muted
- Captions, metadata, secondary labels.
- line
- Borders and dividers.
- action
- The one colour that means "you can do something here": buttons, links, focus.
- on-action
- Text and icons placed on the action colour.
- danger, success, warning
- Status colours for errors, confirmations and cautions, each with its own on-colour if it's used as a fill.
- Pair every fill with its on-colour. If
actionis a background somewhere,on-actionmust be defined and checked against it. - Keep names short and few. If two tokens always hold the same value, merge them.
- Name states as modifiers:
action-hover,surface-raised, rather than new unrelated names. - Don't encode lightness in semantic names.
text-darkstops making sense in dark mode.
Why it makes themes easy
With semantic names in place, a dark theme is just a second set of values for the same names. In CSS, define the tokens as custom properties on :root, which MDN's custom properties guide describes as the way to give one canonical value to the whole page, and redefine them under a dark-theme selector or media query. Components never change. The same is true for brand edits: retuning action from a teal to a green is one line, and every button, link and focus ring follows.
It also keeps contrast checks manageable. Instead of testing every component, test each meaningful pair once: text on ground, text on surface, text-muted on both, on-action on action, line where it marks a control. Neutral colour palettes for UI covers choosing the values; CSS variables theming covers the mechanics.
Common colour role mistakes
- Components that reach past the semantic layer to a primitive, so a rebrand misses them.
- The action colour reused for decoration, so visitors can't tell what's clickable.
- Status colours used as brand accents: a red that means both "sale" and "error".
- A dark theme made by inverting the primitive scale, which turns muted text into bright text and borders into glare.
- Dozens of near-identical tokens added for one-off cases until nobody knows which to use.
Colour tokens in Anticode
Anticode's design systems use semantic colour tokens from the start. Each defines the same roles as CSS custom properties: ground, surface, text, muted text, line, action, the colour on the action, and a second accent some systems use for decoration, each in a light and a dark set. Choosing Light or Dark in the visual editor swaps the set, and choosing an action colour, from red, orange, gold, green, teal, blue, pink or black, changes the one action role everywhere it's used.
In Pro mode, the code editor maps the :root colour tokens back to the project, so you can tune individual tokens, such as warming the ground or deepening the muted text, and the change is kept. That's the main kind of hand edit to styling the code editor keeps; other CSS changes are flagged and not kept. Design tokens explained covers tokens beyond colour.
Questions people ask
What's the difference between primitive and semantic tokens?
Primitive tokens name the available colours, such as green-700. Semantic tokens name jobs, such as action or surface, and point at a primitive.
Should tokens be named after colours?
Primitive tokens can be. Semantic tokens shouldn't, because their colour can change while the job stays the same.
How many colour tokens does a website need?
A small site works well with eight to twelve semantic tokens: ground, surface, text, muted text, line, action, on-action and a few status colours.