Design Tokens vs CSS-Variablen: Was ist der Unterschied?
Zwei Dateien liegen nebeneinander offen. tokens.json sagt
"brand-600": { "$value": "#2563eb", "$type": "color" }; variables.css
sagt --color-brand-600: #2563eb;. Gleicher Wert, fast gleicher Name — und
die naheliegende Frage ist, welche der beiden du eigentlich schreiben sollst.
Die Antwort: Sie sind keine Konkurrenten, sondern Quelle und Ausgabe. Design Tokens sind die Quelle — Design-Entscheidungen, gespeichert in einer tool-neutralen Datei. CSS Custom Properties sind ein Export — dieselben Entscheidungen, gerendert für Browser. Eine nützliche Analogie kommt von Compilern, und es ist eine Analogie: Die Tokens-Datei ist der Quellcode, das Stylesheet ist ein Build-Target, und Figma Variables oder native Ressourcen sind Geschwister-Targets, die aus derselben Quelle generiert werden. Die Unterscheidung klingt akademisch, ist es aber nicht; sie entscheidet, was deine Entscheidungen konsumieren kann, was Tooling prüfen kann und wer was reviewt. Die Quell-Seite behandeln wir durchgehend in unserem Leitfaden zu Design Tokens — dieser Artikel handelt von der Grenze selbst.
Was erreichen Tokens, das CSS-Variablen nicht können?
Alles außer Browsern. Eine Custom Property ist ein CSS-Feature: Sie erreicht
alles, was ein Stylesheet erreicht, und nichts sonst. Die Entscheidungen in
einem Produkt reichen weiter — dasselbe Blau und dieselben Abstände müssen in
der Figma-Datei halten, in den iOS- und Android-Apps, in den E-Mail-Templates,
im Foliensatz, den das Vertriebsteam exportiert. Wenn variables.css die
Source of Truth ist, wird jeder dieser Konsumenten per Handabschrift gespeist —
und handgemachte Kopien driften.
Eine Tokens-Datei speist sie alle als generierte Ansichten: Custom Properties fürs Web, Figma Variables fürs Design, Plattform-Ressourcen für Native. Der Tag, an dem ein zweiter Konsument auftaucht, ist der Tag, an dem der Unterschied aufhört, theoretisch zu sein — bei einem Konsumenten sind die beiden Ansätze kaum zu unterscheiden; bei zweien hat nur einer von ihnen eine Quelle.
Was weiß eine Tokens-Datei, das ein Stylesheet nicht weiß?
Bedeutung. Für CSS ist --brand-600 ein untypisierter Wert, der dort
eingesetzt wird, wo er verwendet wird; nichts in der Sprache weiß, dass es eine
Farbe ist, und ein Tippfehler darin schlägt zur Nutzungszeit still fehl. Eine
Tokens-Datei weiß mehr: $type sagt, dass der Wert eine Farbe ist,
$description sagt, wofür er da ist, und eine Referenz hält fest, dass
accent als {color.brand.600} definiert ist — und nicht nur zufällig
denselben Wert hat.
Auf diesem Wissen läuft das Tooling. Ein Build kann die Datei validieren — eine fehlerhafte Farbe oder eine Referenz auf einen nicht existierenden Token ablehnen —, bevor irgendetwas ausgeliefert wird. Dokumentation kann generiert statt geschrieben werden. Transforms lassen sich mechanisch anwenden: px zu rem, hex zu OKLCH, eine Quelle, gerendert nach den Konventionen des jeweiligen Targets. Nichts davon steht einem nackten Stylesheet zur Verfügung, denn das Stylesheet speichert Antworten ohne ihre Fragen.
Wie wird aus einem Token eine CSS-Variable?
Mechanisch. Drei Tokens als DTCG-Quelle:
{
"color": {
"brand": { "600": { "$value": "#2563eb", "$type": "color" } }
},
"spacing": {
"4": { "$value": "23px", "$type": "dimension" }
},
"semantic": {
"accent": { "$value": "{color.brand.600}", "$type": "color" }
}
}
Und der :root-Block, der daraus generiert wird:
:root {
--color-brand-600: #2563eb; /* oklch(0.546 0.215 262.9) */
--spacing-4: 23px;
--color-accent: var(--color-brand-600);
}
Namen werden zu Property-Namen, Werte werden übernommen, und — das ist das
Detail, das es zu bemerken lohnt — die Referenz überlebt als var(): Der
Export bewahrt die Struktur der Entscheidung, nicht nur ihre aktuelle
Antwort. Komponenten konsumieren die Ausgabe dann ganz normal:
.card {
padding: var(--spacing-4);
background: var(--color-accent);
}
Sieh dir Quelle und Exporte nebeneinander in Scale Composer an — auf der einen Seite die DTCG-Datei, auf der anderen dieselben Namen, gerendert als CSS Custom Properties, ein Tailwind-v4-Theme und Figma Variables; ändere die Quelle, und alle drei Ausgaben bewegen sich gemeinsam.

Leben Tokens und Variablen unterschiedliche Lebenszyklen?
Ja, und der Unterschied zeigt sich im Code-Review. Tokens sind
Design-Entscheidungen: Sie
werden vorgeschlagen, reviewt, versioniert und gedifft — ein Pull Request, der
accent von einem Primitive auf ein anderes umstellt, ist eine
Design-Änderung in Gestalt eines reviewbaren Diffs, und sowohl Designer als
auch Entwickler haben das Recht, dazu Stellung zu nehmen. Das generierte
variables.css ist Implementierungsdetail: ein Build-Artefakt, das neu
generiert und nicht bearbeitet wird. Ein generiertes Stylesheet von Hand zu
bearbeiten hat dieselbe Lebensdauer wie jede von Hand bearbeitete
Compiler-Ausgabe — bis zum nächsten Build.
Die praktische Regel, die daraus folgt: Reviewe die Quelle, generiere das Target, und lass keinen Wert ins Stylesheet, der nicht durch die Quelle gekommen ist.
Wann reichen CSS-Variablen allein ehrlicherweise aus?
Wenn es einen einzigen Konsumenten gibt und es womöglich nie mehr als einen
geben wird. Ein Web-Produkt für eine einzige Plattform ohne Figma-Handoff,
gepflegt von denen, die es geschrieben haben, verliert wenig, wenn es seine
Custom Properties direkt deklariert — die Datei ist einfacher, die Toolchain
kürzer, und ein disziplinierter :root-Block mit rollenbenannten Properties
fängt einen Großteil des Benennungs-Nutzens ein, ganz ohne
Token-Infrastruktur. Das ist eine legitime Entscheidung, keine minderwertige.
Die Token-Schicht rechtfertigt ihre Kosten, wenn die Konsumenten sich vervielfachen: die erste Figma-Bibliothek, die zum Code passen soll, die erste native Oberfläche, das erste zweite Theme. Die Maschinerie schon davor einzuführen heißt, für eine Reichweite zu zahlen, die du noch nicht nutzt — als Vorbereitung vernünftig, aber nicht verpflichtend.
Was fügen CSS-Variablen zur Laufzeit hinzu?
Eine Sache, die Tokens allein nicht können: das Live-Neuauflösen im Browser. Custom Properties werden über die Kaskade aufgelöst — die Mechanik ist in MDNs Leitfaden zu CSS custom properties dokumentiert —, sodass ihr erneutes Deklarieren innerhalb eines Scopes jeden Konsumenten auf einmal umschaltet, ohne dass irgendetwas neu kompiliert werden muss:
[data-theme="dark"] {
--color-accent: oklch(0.70 0.14 262.9); /* neu abgeleiteter Dark-Wert */
}
Jedes var(--color-accent) auf der Seite löst sich in dem Moment neu auf, in
dem das Attribut landet. Das ist eine Eigenschaft des Ausgabeformats, nicht der
Quelle — ein Grund, warum der CSS-Export das richtige Target ist, auch wenn die
Tokens die Quelle sind, und der Mechanismus, auf dem Theme-Systeme aufbauen.
Welche Werte das Dark-Theme halten sollte, ist
ein eigenes Thema; hier genügt es, dass
der Wechsel einen einzigen Deklarationsblock kostet.
Generiere deine Variablen aus einer Quelle
Die Grenze ist am klarsten, wenn du sie bewusst überschreitest. Exportiere CSS Custom Properties aus einer Token-Quelle — ändere eine Entscheidung auf der Quell-Seite (eine Ausgangsfarbe, eine Stufe der Skala), exportiere neu und lies den Diff auf der CSS-Seite: Die Variablen aktualisieren sich, die Referenz-Struktur hält, und nichts musste von Hand bearbeitet werden.