Home: Mohammad Abu-aishehOpen to work Open to work العربية

UI & visual design // Guide

Colour tokens: primitive and semantic

Name colours by role, not by hue. Primitive and semantic tokens make states, dark mode and theming cheaper to build and maintain.

Colour tokens: primitive and semantic

Two layers of tokens

Colour tokens usually come in two layers. Primitive tokens are the raw palette, such as blue-500 or gray-100. Semantic tokens describe a job, such as text-primary, surface, border, accent and danger. Components use only the semantic layer, and each semantic token points to a primitive.

Name by role and plan the states

A token called blue-button breaks the moment the brand turns green. A token called accent survives the change, because only its value moves. Role names also tell developers where a colour belongs.

  • Text: text-primary, text-secondary, text-disabled
  • Surfaces: surface, surface-raised
  • Borders: border, border-strong
  • Accent: accent, accent-hover, accent-active
  • Feedback: danger, success, warning

Plan states early. Hover, active, focus and disabled each need a defined value rather than an improvised one.

Interactive elements change appearance, and each change deserves a token. A button might use accent for its default fill, accent-hover for the pointer-over state and accent-active while pressed. A disabled control uses a muted pair, such as text-disabled on a surface-muted fill.

  • Hover: slightly darker or lighter than the default.
  • Active: one more step than hover.
  • Focus: a clearly visible ring that does not depend on colour alone.
  • Disabled: lower emphasis, but disabled controls are exempt from contrast requirements, so keep the label legible anyway.

Never use colour as the only signal. Pair danger red with an icon or a text label.

Cheap dark mode and theming

When components reference only semantic tokens, a new theme means reassigning those tokens. Nothing inside the components changes. CSS custom properties make this direct:

Light theme: <code>:root { --surface: #ffffff; --text-primary: #1a1a1a; }</code>

Dark theme: <code>@media (prefers-color-scheme: dark) { :root { --surface: #1c1c1e; --text-primary: #ececec; } }</code>

Components then use <code>background: var(--surface)</code> and never a raw hex value.

Check contrast per token pair

Tokens do not guarantee readable colour. Check each pair that appears together, in every theme. WCAG asks for at least 4.5:1 for body text and 3:1 for large text and UI components such as borders of inputs.

  1. List the pairs that appear together: text-primary on surface, accent on surface, and text on accent.
  2. Measure each pair with a contrast checker.
  3. Record the result next to the token.
  4. Repeat for dark mode and for disabled states.

Document every approved pair in the design system, so contrast is checked once instead of on every screen.

Tokens also help with handoff. Developers copy a token name instead of a hex code, and a later brand update changes one value in one place. Keep the primitive palette small, usually a handful of neutrals plus one or two hues with several lightness steps each.

Sources

  • W3C. Web Content Accessibility Guidelines (WCAG) 2.2. https://www.w3.org/TR/WCAG22/
  • MDN Web Docs. Using CSS custom properties (variables). https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties

This guide was drafted with AI assistance from public standards and references. For the exact wording of a standard, use the sources listed above.

More on this topic

  • UI & visual design2 min read

    Layout grids: columns, gutters, margins

    A grid brings order to layouts. Learn columns, gutters and margins, content-led breakpoints, comfortable line length and CSS grid basics.

  • UI & visual design2 min read

    Designing dark mode properly

    Dark mode is not an inversion. Learn soft surfaces, off-white text, elevation by lightness, adjusted accents and how to honour user settings.

  • UI & visual design2 min read

    Designing useful empty states

    An empty screen is a chance to guide people. Learn the four kinds of empty state, what each should say, and how to avoid dead ends.

Keyboard shortcuts
Single-key shortcuts

Turn off if you use speech input or find them getting in the way.