</>
tw
Tailwind CSS · Design-Tokens · @theme · Design-System · v4
Tailwind CSS Design-Token-System in v4
@theme als Single Source of Truth für alle Tokens

Ein durchdachtes Design-Token-System ist die Grundlage jedes skalierbaren Frontend-Projekts. Mit Tailwind CSS v4 und @theme werden Design-Tokens zu CSS Custom Properties, die gleichzeitig als Tailwind-Utilities, in CSS-Eigenschaften und in JavaScript verfügbar sind – eine echte Single Source of Truth für Farben, Typografie, Spacing und mehr.

15 Min. Lesezeit @theme · CSS Custom Properties · Semantic Tokens · Multi-Theme · Design-System Tailwind CSS v4.0+

1. Was sind Design-Tokens und warum braucht man sie?

Design-Tokens sind benannte, wiederverwendbare Designentscheidungen – Farben, Schriftgrößen, Abstände, Radien, Schatten –, die zentral definiert und im gesamten Projekt konsistent verwendet werden. Statt den Hex-Wert #2563eb an hundert Stellen im Code zu verwenden, definiert man einen Token --color-interactive und referenziert diesen überall. Wenn sich der Markenwert ändert, reicht eine einzige Änderung am Token – und das gesamte Projekt aktualisiert sich automatisch.

Der entscheidende Vorteil von Design-Tokens mit Tailwind CSS v4 und @theme: Die Tokens existieren als CSS Custom Properties im :root und sind damit universell verfügbar – als Tailwind-Utility-Klassen, direkt in CSS-Eigenschaften und in JavaScript über getComputedStyle. Das löst eines der fundamentalen Probleme bei der Arbeit mit Tailwind in großen Teams: die Diskrepanz zwischen den Werten in tailwind.config.js (die nur zur Build-Zeit existieren) und den tatsächlichen Laufzeit-Werten. Mit @theme als Design-Token-System gibt es diese Diskrepanz nicht mehr.

In der Praxis bedeutet das: Ein Design-System, das auf Tailwind CSS v4 Design-Tokens aufbaut, kann dieselben Token-Werte in Tailwind-Klassen (text-interactive), in CSS Custom Properties (color: var(--color-interactive)) und in JavaScript (getComputedStyle(root).getPropertyValue('--color-interactive')) verwenden. Drei Verwendungsarten, eine Quelle der Wahrheit – das ist die Grundlage eines robusten, wartbaren Design-Systems.

2. Drei Ebenen: Primitive, Semantische und Komponenten-Tokens

Ein professionelles Design-Token-System besteht aus drei Hierarchieebenen. Auf der untersten Ebene stehen die Primitive Tokens: rohe Werte ohne Semantik – alle Blau-Schattierungen von 50 bis 950, alle Spacing-Werte von 1 bis 128, alle Schriftgrößen. Diese Tokens beschreiben was ein Wert ist, nicht wozu er verwendet wird. In Tailwind CSS v4 @theme sind das die üblichen --color-blue-500-, --spacing-4- und --text-base-Tokens.

Auf der mittleren Ebene stehen die Semantischen Tokens: Sie beschreiben die Verwendung eines Werts, nicht seinen konkreten Inhalt. --color-interactive sagt "dieser Wert ist für interaktive Elemente", --color-surface-elevated sagt "dieser Wert ist für erhöhte Oberflächen". Semantische Tokens referenzieren Primitive Tokens: --color-interactive: var(--color-blue-600). Das ermöglicht Theme-Wechsel durch Überschreiben der Primitiven – man ändert --color-blue-600 zu einer anderen Farbe, und alle semantischen Tokens, die darauf zeigen, ändern sich mit.

Die oberste Ebene sind Komponenten-Tokens: Token für spezifische UI-Komponenten wie --button-background, --card-border-radius oder --input-border-color. Sie referenzieren semantische Tokens (--button-background: var(--color-interactive)) und erlauben feingranulare Kontrolle über einzelne Komponenten, ohne semantische Tokens zu überladen. Für kleine bis mittelgroße Projekte reichen meist Primitive und Semantische Tokens; Komponenten-Tokens kommen bei größeren Design-Systemen mit vielen Entwicklern und strikten Design-Anforderungen ins Spiel.

3. Farb-Token-System mit @theme aufbauen

Das Farb-Token-System ist das Herzstück jedes Design-Token-Systems mit Tailwind CSS v4. Eine bewährte Struktur besteht aus zwei Schichten: einer vollständigen Farbpalette als Primitive Tokens und einem semantischen Layer, der die Verwendungsabsicht beschreibt. Die Farbpalette umfasst in der Regel eine Primärfarbe mit 10–11 Schattierungen (50 bis 950), eine Neutralfarbe für Text und Hintergründe, und optional Akzent-, Erfolg-, Warn- und Fehlerfarben.

Im Tailwind CSS v4 @theme-System werden diese Paletten als Primitive Tokens definiert, und dann werden semantische Tokens erstellt, die auf die Paletten verweisen. Der entscheidende Vorteil dieses zweistufigen Ansatzes: Um von einem blauen Primärthema zu einem grünen zu wechseln, überschreibt man nur die semantischen Token-Werte. Statt --color-interactive: var(--color-blue-600) schreibt man --color-interactive: var(--color-green-600) – und alle Elemente, die bg-interactive oder text-interactive verwenden, wechseln automatisch die Farbe.


/* tokens/colors.css — Complete color token system for Tailwind CSS v4 */
@theme {
  /* === PRIMITIVE TOKENS: raw color palette === */

  /* Primary blue palette */
  --color-primary-50:  #eff6ff;
  --color-primary-100: #dbeafe;
  --color-primary-200: #bfdbfe;
  --color-primary-300: #93c5fd;
  --color-primary-400: #60a5fa;
  --color-primary-500: #3b82f6;
  --color-primary-600: #2563eb;
  --color-primary-700: #1d4ed8;
  --color-primary-800: #1e40af;
  --color-primary-900: #1e3a8a;
  --color-primary-950: #172554;

  /* Neutral palette */
  --color-neutral-50:  #f8fafc;
  --color-neutral-100: #f1f5f9;
  --color-neutral-200: #e2e8f0;
  --color-neutral-300: #cbd5e1;
  --color-neutral-400: #94a3b8;
  --color-neutral-500: #64748b;
  --color-neutral-600: #475569;
  --color-neutral-700: #334155;
  --color-neutral-800: #1e293b;
  --color-neutral-900: #0f172a;
  --color-neutral-950: #020617;

  /* Status colors */
  --color-success-500: #22c55e;
  --color-success-700: #15803d;
  --color-warning-500: #f59e0b;
  --color-warning-700: #b45309;
  --color-danger-500:  #ef4444;
  --color-danger-700:  #b91c1c;

  /* === SEMANTIC TOKENS: usage-based naming === */

  /* Interactive elements */
  --color-interactive:        var(--color-primary-600);
  --color-interactive-hover:  var(--color-primary-700);
  --color-interactive-active: var(--color-primary-800);
  --color-interactive-focus:  var(--color-primary-500);

  /* Surfaces & backgrounds */
  --color-background:        var(--color-neutral-50);
  --color-surface:           #ffffff;
  --color-surface-elevated:  var(--color-neutral-100);
  --color-surface-overlay:   var(--color-neutral-200);

  /* Text */
  --color-foreground:        var(--color-neutral-900);
  --color-foreground-muted:  var(--color-neutral-500);
  --color-foreground-subtle: var(--color-neutral-400);

  /* Borders */
  --color-border:            var(--color-neutral-200);
  --color-border-strong:     var(--color-neutral-300);
  --color-border-focus:      var(--color-primary-500);
}

4. Typografie-Tokens: Schriften, Größen und Zeilenhöhen

Typografie-Tokens sind nach Farb-Tokens die wichtigste Kategorie in jedem Design-Token-System mit Tailwind CSS v4. Sie umfassen Schriftfamilien, Schriftgrößen, Schriftgewichte, Zeilenhöhen und Zeichenabstände. Das @theme-Präfix-Schema ist klar strukturiert: --font-* für Schriftfamilien, --text-* für Schriftgrößen, --leading-* für Zeilenhöhen, --tracking-* für Zeichenabstände und --font-weight-* für Schriftgewichte.

Ein wichtiges Prinzip beim Aufbau von Typografie-Tokens: Die Schriftgröße allein sagt wenig aus – erst die Kombination aus Schriftgröße, Zeilenhöhe und Schriftgewicht ergibt einen konsistenten Typografie-Stil. In größeren Design-Token-Systemen definiert man Typografie-Skalen als atomare Tokens (Größe, Höhe, Gewicht separat) und kombiniert diese in Komponenten oder semantischen CSS-Regeln. In Tailwind CSS v4 lässt sich das mit @utility-Definitionen gut lösen: @utility text-display-lg { font-size: var(--text-5xl); line-height: var(--leading-tight); font-weight: 700; }


/* tokens/typography.css — Typografie token system */
@theme {
  /* Font family tokens */
  --font-sans:    "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-display: "Cal Sans", "Inter", ui-sans-serif, sans-serif;
  --font-mono:    "JetBrains Mono", "Fira Code", ui-monospace, monospace;

  /* Font size tokens (generates text-* utilities) */
  --text-2xs: 0.625rem;   /* 10px */
  --text-xs:  0.75rem;    /* 12px */
  --text-sm:  0.875rem;   /* 14px */
  --text-base: 1rem;      /* 16px */
  --text-lg:  1.125rem;   /* 18px */
  --text-xl:  1.25rem;    /* 20px */
  --text-2xl: 1.5rem;     /* 24px */
  --text-3xl: 1.875rem;   /* 30px */
  --text-4xl: 2.25rem;    /* 36px */
  --text-5xl: 3rem;       /* 48px */
  --text-6xl: 3.75rem;    /* 60px */

  /* Line height tokens */
  --leading-tight:    1.25;
  --leading-snug:     1.375;
  --leading-normal:   1.5;
  --leading-relaxed:  1.625;
  --leading-loose:    2;

  /* Letter spacing tokens */
  --tracking-tighter: -0.05em;
  --tracking-tight:   -0.025em;
  --tracking-normal:   0em;
  --tracking-wide:     0.025em;
  --tracking-wider:    0.05em;
  --tracking-widest:   0.1em;
}

/* Composite typography utilities */
@utility text-display {
  font-family: var(--font-display);
  font-size: var(--text-5xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  font-weight: 700;
}

@utility text-heading {
  font-family: var(--font-sans);
  font-size: var(--text-2xl);
  line-height: var(--leading-snug);
  font-weight: 600;
}

5. Spacing-Token-System und das 4px-Raster

Das Spacing-System ist die unsichtbare Grundlage jedes konsistenten UI-Designs. Ein gutes Design-Token-System mit Tailwind CSS v4 baut auf einem mathematisch konsistenten Spacing-Raster auf – in den meisten Projekten ein 4px-Basisraster. Tailwinds Standard-Spacing-Skala folgt bereits einem 4px-Raster (Spacing-1 = 4px, Spacing-4 = 16px, Spacing-8 = 32px), aber das @theme-System erlaubt es, diese Skala gezielt zu erweitern oder für spezifische Projekte anzupassen.

Für Komponenten-spezifisches Spacing empfiehlt sich die Verwendung semantischer Spacing-Tokens: --spacing-card-padding, --spacing-section-gap, --spacing-form-row. Diese Tokens referenzieren die primitiven Spacing-Tokens und machen Spacing-Entscheidungen explizit und nachvollziehbar. Wenn sich die Anforderung ändert – etwa weil auf mobilen Geräten kompakteres Spacing gewünscht wird –, ändert man nur den semantischen Token-Wert und alle Stellen, die diesen Token verwenden, passen sich an. Das ist der Kern des Design-Token-Ansatzes: Änderungen an einer Stelle propagieren systematisch durch das gesamte Tailwind CSS-Projekt.

6. JavaScript-Zugriff auf Design-Tokens

Einer der wichtigsten Vorteile des Tailwind CSS v4 @theme Design-Token-Systems gegenüber dem alten tailwind.config.js-Ansatz ist der Laufzeit-Zugriff auf Tokens über CSS Custom Properties. Da alle @theme-Tokens als :root-Custom Properties im generierten CSS erscheinen, kann JavaScript über getComputedStyle(document.documentElement).getPropertyValue('--color-interactive') auf jeden Token-Wert zugreifen.

Das ermöglicht Anwendungsfälle, die mit dem alten Ansatz nicht möglich waren: Canvas-basierte Visualisierungen, die die aktuellen Theme-Farben verwenden; JavaScript-Animationen, die auf Design-Token-Werte abgestimmt sind; oder Theming-Systeme, die Tokens dynamisch per JavaScript überschreiben. Tokens in JavaScript überschreiben geht über document.documentElement.style.setProperty('--color-interactive', '#new-color') – und sofort ändern sich alle Elemente im DOM, die diesen Token verwenden, ohne dass eine einzige CSS-Datei neu geladen werden muss.


// token-utils.js — JavaScript utilities for accessing Tailwind CSS v4 @theme tokens
'use strict';

const root = document.documentElement;

/**
 * Get the current value of a design token from CSS Custom Properties.
 * Works because @theme tokens are published as :root CSS Custom Properties.
 * @param {string} tokenName - e.g. '--color-interactive', '--spacing-4'
 * @returns {string} The computed token value
 */
function getToken(tokenName) {
  return getComputedStyle(root).getPropertyValue(tokenName).trim();
}

/**
 * Override a design token at runtime — all elements using this token update immediately.
 * @param {string} tokenName - CSS custom property name
 * @param {string} value     - New value
 */
function setToken(tokenName, value) {
  root.style.setProperty(tokenName, value);
}

// Read all color tokens for use in a Canvas chart
const interactiveColor = getToken('--color-interactive'); // '#2563eb'
const surfaceColor     = getToken('--color-surface');     // '#ffffff'
const borderColor      = getToken('--color-border');      // '#e2e8f0'

// Dynamic brand theme switch — no CSS file reload needed
function applyBrandTheme(theme) {
  if (theme === 'partner-a') {
    setToken('--color-interactive',       '#059669');  // Green brand
    setToken('--color-interactive-hover', '#047857');
  } else if (theme === 'partner-b') {
    setToken('--color-interactive',       '#7c3aed');  // Purple brand
    setToken('--color-interactive-hover', '#6d28d9');
  }
}

// Export for use in framework components (Alpine.js, Vue, React...)
export { getToken, setToken, applyBrandTheme };

7. Multi-Theme-Architektur mit @theme und @variant

Für Projekte mit mehreren Themes – White-Label-Produkte, Mandanten-fähige Webanwendungen, oder Websites mit Marken-Varianten – bietet das Tailwind CSS v4 Design-Token-System eine elegante Multi-Theme-Architektur. Die Basis ist ein zentrales Token-Set als Standardtheme in @theme. Theme-Varianten überschreiben nur die Tokens, die sich unterscheiden, statt alles neu zu definieren. Das minimiert Redundanz und macht Theme-Unterschiede auf einen Blick nachvollziehbar.

Die technische Implementierung nutzt @variant-Definitionen für jedes Theme und @theme-Overrides innerhalb dieser Varianten. Alternativ – besonders für Mandanten-Systeme, bei denen Themes server-seitig zugewiesen werden – überschreibt man Tokens in einem datenattribut-basierten Selektor: [data-theme="partner-a"] { --color-interactive: var(--color-green-600); }. Dieser Ansatz ermöglicht es, Themes zur Laufzeit per JavaScript zu wechseln (document.documentElement.setAttribute('data-theme', 'partner-a')) ohne den Tailwind-Build neu auszuführen – ein wesentlicher Vorteil für dynamische White-Label-Systeme.

8. Design-Token-Ansätze im Vergleich

Der direkte Vergleich zeigt, warum Tailwind CSS v4 @theme als Design-Token-System anderen Ansätzen überlegen ist.

Ansatz Laufzeit-Zugriff Tailwind-Utilities Multi-Theme JS-Overhead
@theme (Tailwind v4) CSS Custom Properties Automatisch @variant + override Keiner
tailwind.config.js (v3) Nur Build-Zeit Automatisch Mehrere Builds JS Config-Parse
Reine CSS Custom Properties Ja Nicht generiert Selektor-Override Keiner
Style Dictionary / Token-Tool Exportiert Manuell / Plugin Multiple Outputs Build-Tool nötig

Tailwind CSS v4 @theme kombiniert die Vorteile aller Ansätze: automatische Utility-Generierung wie in v3, Laufzeit-Zugriff wie bei reinen CSS Custom Properties und einfache Multi-Theme-Fähigkeit ohne externe Tools. Der einzige Aspekt, bei dem spezialisierte Token-Tools wie Style Dictionary überlegen sind, ist die plattformübergreifende Token-Synchronisation – wenn dieselben Tokens in iOS, Android und Web gleichzeitig genutzt werden sollen. Für reine Web-Projekte ist @theme als Design-Token-System der klarste und wartbarste Ansatz.

9. Dateistruktur für große Design-Token-Systeme

Ein Design-Token-System mit Tailwind CSS v4 wächst mit der Projektgröße. Für kleine Projekte reicht ein einzelner @theme-Block in der Hauptdatei. Für mittlere bis große Projekte – mit mehreren Entwicklern, mehreren Themes oder einem vollständigen Design-System – empfiehlt sich eine klare Verzeichnisstruktur. Die Erfahrung aus realen Projekten zeigt, dass eine Token-Hierarchie nach Kategorie (Farben, Typografie, Spacing, Effekte) und innerhalb jeder Kategorie nach Ebene (Primitive, Semantisch, Komponenten) die wartbarste Struktur ergibt.

Eine bewährte Struktur für Tailwind CSS v4 Design-Token-Projekte: Ein tokens/-Verzeichnis mit Dateien pro Token-Kategorie, ein themes/-Verzeichnis für Theme-Overrides, ein utilities/-Verzeichnis für @utility-Definitionen und eine app.css-Hauptdatei, die alles per @import zusammenführt. Diese Struktur skaliert von einem einzelnen Entwickler bis zu einem Team von zehn und macht den Unterschied zwischen einem Design-Token-System, das nach sechs Monaten zur Blackbox wird, und einem, das weiterhin wartbar und erweiterbar bleibt.


/* app.css — Main entry for Tailwind CSS v4 Design Token System */
@import "tailwindcss";

/* Source configuration — explicit paths for non-standard project structures */
@source "../templates/**/*.{html,phtml,php}";
@source "../src/**/*.{js,ts,vue,jsx,tsx}";

/* === TOKEN LAYERS === */

/* Primitive tokens — raw values without semantic meaning */
@import "./tokens/primitives/colors.css";
@import "./tokens/primitives/typography.css";
@import "./tokens/primitives/spacing.css";
@import "./tokens/primitives/effects.css";

/* Semantic tokens — usage-based naming referencing primitives */
@import "./tokens/semantic/colors.css";
@import "./tokens/semantic/typography.css";
@import "./tokens/semantic/spacing.css";

/* Component tokens — component-specific token overrides */
@import "./tokens/components/button.css";
@import "./tokens/components/card.css";
@import "./tokens/components/form.css";

/* === THEMES (override semantic tokens) === */
/* Default theme is defined in semantic tokens above */
/* @import "./themes/partner-a.css"; — loaded conditionally */
/* @import "./themes/dark.css";      — loaded via @variant dark */

/* === LAYERS === */
@import "./layers/base.css";
@import "./layers/utilities.css";
@import "./layers/components.css";

/* Folder structure:
   tokens/
   ├── primitives/  colors.css, typography.css, spacing.css, effects.css
   ├── semantic/    colors.css, typography.css, spacing.css
   └── components/  button.css, card.css, form.css, ...
   themes/
   ├── dark.css, partner-a.css, partner-b.css
   layers/
   ├── base.css, utilities.css, components.css
*/

10. Zusammenfassung

Ein Design-Token-System mit Tailwind CSS v4 und @theme ist die reifste und wartbarste Architektur für Frontend-Projekte jeder Größe. Die drei-Ebenen-Struktur aus Primitiven, Semantischen und Komponenten-Tokens gibt Teams die Kontrolle, konsistente Designs zu erstellen, Themes flexibel zu wechseln und Änderungen systematisch durch das gesamte Projekt zu propagieren. Die @theme-Direktive macht Design-Tokens zu CSS Custom Properties – was bedeutet, dass dieselben Werte als Tailwind-Utilities, in CSS-Eigenschaften und in JavaScript verfügbar sind.

Der praktische Gewinn: Statt Hex-Werte an hunderten von Stellen zu ändern, ändert man einen Token. Statt für Dark Mode doppelte Klassen in HTML zu schreiben, überschreibt man Token-Werte in einem @variant dark-Block. Statt für White-Label-Varianten separate Builds zu erstellen, überschreibt man semantische Tokens per JavaScript-Laufzeit. Das Tailwind CSS v4 Design-Token-System ist nicht nur eine Konfigurationsmethode – es ist eine Denkweise für skalierbare, wartbare Frontend-Architektur.

Tailwind CSS Design-Token-System in v4 — Das Wichtigste auf einen Blick

Drei Ebenen

Primitive Tokens (raw values) → Semantische Tokens (usage-based) → Komponenten-Tokens (component-specific). Ändert man eine Ebene, propagiert es nach oben.

Single Source of Truth

@theme-Tokens als :root Custom Properties – gleichzeitig als Tailwind-Utilities, in CSS var() und in JavaScript getComputedStyle verfügbar.

Multi-Theme

@variant-Blöcke oder data-attribute-Selektoren für Theme-Overrides. Runtime-Switching per JavaScript ohne Rebuild möglich.

Dateistruktur

tokens/primitives/ → tokens/semantic/ → tokens/components/ → themes/. Pro Kategorie eine Datei, per @import zusammengeführt.