Design Tokens & CSS Variables

One Source of Truth for Your System

Design Tokens & CSS Variables

Theme tokens are exposed as CSS custom properties, enabling runtime theming and integration with design tooling.

4 min read Level 3/5 #tailwind#tokens#theming
What you'll learn
  • Read tokens at runtime via var(--color-brand)
  • Re-theme by overriding variables within a scope
  • Use token namespaces to control which utilities are generated

A @theme token is not a build-time constant — it compiles to a live CSS custom property on :root. That single fact unlocks runtime theming.

Tokens at Runtime

After defining --color-brand, it exists in the browser as a regular variable:

:root {
  --color-brand: oklch(0.62 0.19 256);
}

.custom-callout {
  border-left: 4px solid var(--color-brand);
}

JavaScript can read or set it with getComputedStyle and style.setProperty, so the same token drives utilities, custom CSS, and dynamic behaviour.

Re-Theming by Scope

Override the variable inside a class or attribute and every *-brand utility under that scope re-skins instantly — no rebuild:

.theme-acme {
  --color-brand: oklch(0.55 0.21 25);
}

.theme-globex {
  --color-brand: oklch(0.7 0.15 160);
}
<section class="theme-acme">
  <button class="bg-brand text-white">Acme red</button>
</section>

This is how multi-brand sites and per-user themes work in v4: one token, scoped overrides.

Namespaces Drive Generation

The token namespace is meaningful, not cosmetic. It tells Tailwind which family of utilities to emit:

@theme {
  --color-ink: oklch(0.2 0 0);
  --spacing-bay: 3rem;
  --radius-pill: 9999px;
  --text-display: 3.5rem;
}

--color-* becomes color utilities, --spacing-* becomes spacing utilities, --radius-* becomes rounded-*, and --text-* becomes font-size utilities. Keeping tokens correctly namespaced is what keeps the generated utility surface coherent.

Custom Utilities with @utility →