aus einer einzigen Markenfarbe die volle Tailwind-Skala bauen
Ein Designteam liefert meist genau einen Hex-Wert für die Markenfarbe, aber Tailwind erwartet eine vollständige Skala von 50 bis 950 für Hintergründe, Rahmen, Text und Hover-Zustände. Wer diese elf Stufen von Hand in einem Grafikprogramm zusammenklickt, bekommt selten ein konsistentes Ergebnis, weil sich Helligkeit und Sättigung ohne festen Farbraum kaum gleichmäßig abstufen lassen. Mit einer OKLCH-basierten Interpolation lässt sich dieser Prozess automatisieren und liefert Skalen, die sich genauso gleichmäßig anfühlen wie Tailwinds eingebaute Paletten.
Inhaltsverzeichnis
- 1. Das Problem: eine Markenfarbe, aber elf benötigte Stufen
- 2. Warum OKLCH statt HSL für die Interpolation
- 3. OKLCH-Syntax in CSS: Lightness, Chroma, Hue
- 4. Die Lightness-Chroma-Kurve für elf Stufen planen
- 5. Ein einfaches Generierungsskript mit der Bibliothek culori
- 6. Fertige Tools statt Eigenbau: uicolors.app, Tailwind Shades und Co.
- 7. Integration ins @theme von Tailwind v4
- 8. Kontrastprüfung und manuelle Nachjustierung
- 9. Häufige Fehler und Fazit für den eigenen Workflow
- 10. Zusammenfassung
- 11. FAQ
1. Das Problem: eine Markenfarbe, aber elf benötigte Stufen
Ein Styleguide vom Kunden enthält typischerweise nur einen einzigen Hex-Code für die Markenfarbe, etwa #0ea5e9 für ein bestimmtes Blau. Tailwind selbst arbeitet aber konsequent mit einer Skala aus elf Stufen, von 50 als hellstem Hintergrundton bis 950 als fast schwarzem Text- und Kontrastwert. Jede dieser Stufen hat im UI eine feste Rolle: Fünfzig und Hundert dienen als dezente Flächenfarben, Fünfhundert markiert meist den Basiswert für Buttons und Links, Siebenhundert bis Neunhundert liefern Text mit ausreichendem Kontrast auf hellem Grund.
Wird diese Skala nicht sauber aus der Markenfarbe abgeleitet, entstehen schnell Bruchstellen im Design: Ein Hover-Zustand wirkt plötzlich wärmer oder kälter als der Grundton, oder die dunkelste Stufe kippt unbeabsichtigt ins Violette statt konsistent Richtung Schwarzblau zu gehen. Ein automatisierter Generator löst dieses Problem strukturell, indem er aus dem einen Ausgangswert alle elf Stufen nach einer festen, nachvollziehbaren Regel ableitet, statt sie einzeln von Hand nachzujustieren.
2. Warum OKLCH statt HSL für die Interpolation
Der naheliegende Ansatz wäre, den Hex-Wert nach HSL umzurechnen und die Lightness-Komponente in gleichmäßigen Schritten zwischen hell und dunkel zu verschieben. Das Problem dabei: HSL-Lightness entspricht nicht der tatsächlich wahrgenommenen Helligkeit einer Farbe. Ein reines Gelb bei fünfzig Prozent HSL-Lightness wirkt für das menschliche Auge deutlich heller als ein Blau bei derselben HSL-Lightness, weshalb aus HSL abgeleitete Skalen bei manchen Farbtönen hübsch gleichmäßig aussehen und bei anderen plötzlich einen sichtbaren Helligkeitssprung zwischen zwei Nachbarstufen zeigen.
OKLCH löst genau dieses Problem, weil sein L-Kanal auf dem perzeptuell gleichmäßigen Oklab-Farbraum basiert und tatsächlich der menschlichen Helligkeitswahrnehmung folgt. Zwei Farben mit demselben L-Wert wirken für das Auge gleich hell, unabhängig davon, ob es sich um Gelb, Blau oder Rot handelt. Genau deshalb nutzt auch Tailwind selbst seit Version vier OKLCH als internen Farbraum für die eingebauten Paletten, und ein eigener Generator, der demselben Prinzip folgt, fügt sich nahtlos in dieses System ein.
3. OKLCH-Syntax in CSS: Lightness, Chroma, Hue
In CSS wird eine OKLCH-Farbe als oklch(L C H) notiert, wobei L die Helligkeit zwischen null und eins angibt, C die Chroma also die Farbsättigung als positiven Wert ohne festes Maximum, und H den Farbton als Winkel zwischen null und dreihundertsechzig Grad. Diese drei Werte lassen sich unabhängig voneinander variieren, was für eine Farbskala genau die Kontrolle liefert, die man braucht: Der Hue bleibt über alle elf Stufen weitgehend konstant, während Lightness und Chroma gezielt in Richtung hell oder dunkel verschoben werden.
Wichtig ist dabei, dass Chroma nicht einfach linear mit der Lightness mitlaufen darf. Sehr helle und sehr dunkle Farben können physikalisch nur eine begrenzte Sättigung erreichen, bevor sie aus dem darstellbaren sRGB-Gamut herausfallen. Ein guter Generator reduziert die Chroma an den Rändern der Skala automatisch etwas, damit die Farbe im Browser nicht auf einen unerwünschten Ersatzwert geklemmt wird, sondern kontrolliert innerhalb des darstellbaren Bereichs bleibt.
/* Eine Stufe der generierten Skala in CSS */
.swatch-500 {
/* L = 0.63, C = 0.19, H = 235 Grad (Blauton) */
background-color: oklch(0.63 0.19 235);
}
/* Zum Vergleich: dieselbe Farbe als Fallback in sRGB */
.swatch-500-fallback {
background-color: #0ea5e9;
}
4. Die Lightness-Chroma-Kurve für elf Stufen planen
Bevor ein Skript loslegt, lohnt es sich, die Zielwerte für Lightness an jeder der elf Stufen grob festzulegen, angelehnt an Tailwinds eigene Paletten. Stufe fünfzig liegt typischerweise bei einer Lightness von etwa siebenundneunzig bis achtundneunzig Prozent, Stufe fünfhundert oft irgendwo zwischen fünfzig und siebzig Prozent je nach Ausgangsfarbe, und Stufe neunhundertfünfzig fällt auf etwa zwölf bis fünfzehn Prozent. Diese Werte bilden eine Kurve, keine lineare Gerade, weil der wahrgenommene Helligkeitsunterschied an den Enden der Skala stärker komprimiert werden sollte als in der Mitte.
Für die Chroma gilt eine ähnliche Logik: Sie steigt von Stufe fünfzig bis etwa vier- oder fünfhundert an und fällt danach wieder leicht ab, weil sehr dunkle, stark gesättigte Farben im sRGB-Raum schnell an ihre Grenzen stoßen. Ein Generator, der diese Kurve als Parameter konfigurierbar macht, statt sie hart zu verdrahten, lässt sich später leicht an andere Markenfarben mit ganz unterschiedlichem Ausgangs-Hue anpassen, ohne den Kern des Skripts neu schreiben zu müssen.
5. Ein einfaches Generierungsskript mit der Bibliothek culori
Für die praktische Umsetzung eignet sich die JavaScript-Bibliothek culori besonders gut, weil sie Konvertierungen zwischen Hex, OKLCH und weiteren Farbräumen bereits fertig mitbringt und auch das Gamut-Mapping für sRGB übernimmt. Ein Skript liest die Marken-Hex-Farbe ein, wandelt sie nach OKLCH um, übernimmt deren Hue als konstanten Wert für alle Stufen und berechnet für jede der elf Stufen ein Lightness-Chroma-Paar nach der zuvor geplanten Kurve.
Das Ergebnis lässt sich direkt als Liste von CSS-Custom-Properties ausgeben, die anschließend ins Tailwind-Theme kopiert werden. Wichtig ist, den ursprünglichen Hex-Wert der Markenfarbe nicht zwingend exakt auf Stufe fünfhundert zu mappen, sondern die nächstgelegene Stufe zu identifizieren und dort die Original-Chroma beizubehalten, damit die Marke in der Skala wiedererkennbar bleibt und nicht durch die Interpolation verwaschen wird.
import { formatHex, oklch, converter } from 'culori';
const toOklch = converter('oklch');
// Zielkurve: [L, C] je Stufe, Hue kommt aus der Markenfarbe
const CURVE = {
50: [0.98, 0.02], 100: [0.95, 0.045], 200: [0.90, 0.075],
300: [0.82, 0.11], 400: [0.72, 0.15], 500: [0.63, 0.19],
600: [0.54, 0.18], 700: [0.45, 0.15], 800: [0.36, 0.11],
900: [0.28, 0.08], 950: [0.16, 0.045],
};
function generateScale(brandHex) {
const base = toOklch(brandHex);
const scale = {};
for (const [step, [l, c]] of Object.entries(CURVE)) {
scale[step] = formatHex({ mode: 'oklch', l, c, h: base.h });
}
return scale;
}
console.log(generateScale('#0ea5e9'));
6. Fertige Tools statt Eigenbau: uicolors.app, Tailwind Shades und Co.
Nicht jedes Projekt braucht ein selbst geschriebenes Skript. Im Oekosystem existieren bereits mehrere ausgereifte Generatoren, die eine Markenfarbe per Hex-Eingabe entgegennehmen und direkt eine fertige Tailwind-Konfiguration ausspucken. uicolors.app zeigt die generierte Skala live als Vorschau mit Kontrastwerten und exportiert wahlweise als JavaScript-Objekt oder als CSS-Custom-Properties für das v4-Theme. Tailwind Shades verfolgt einen ähnlichen Ansatz, erlaubt aber zusätzlich, einzelne Stufen manuell per Slider nachzujustieren, bevor der Export erfolgt.
Für Teams, die lieber ein etabliertes, bereits durchdachtes Stufensystem übernehmen möchten, lohnt sich ein Blick auf Radix Colors: Dort sind für jede Basisfarbe zwölf Stufen mit klar dokumentierter Verwendungsabsicht vordefiniert, inklusive separater Skalen für Light- und Dark-Mode. Der Nachteil gegenüber einem eigenen Generator ist, dass sich die exakte Markenfarbe damit nicht immer eins zu eins treffen lässt, weil Radix von vordefinierten Referenztönen ausgeht statt von einem beliebigen Eingabewert.
7. Integration ins @theme von Tailwind v4
Tailwind v4 verzichtet auf die klassische JavaScript-Konfigurationsdatei zugunsten eines CSS-first-Ansatzes: Design-Tokens werden direkt im Stylesheet innerhalb eines @theme-Blocks als CSS-Custom-Properties definiert. Die generierte Farbskala landet dort als Liste von Variablen mit dem Präfix --color-brand-, gefolgt von der jeweiligen Stufe, also etwa --color-brand-500: oklch(0.63 0.19 235);. Tailwind erkennt dieses Namensschema automatisch und erzeugt daraus sämtliche Utility-Klassen wie bg-brand-500, text-brand-700 oder border-brand-200, ganz ohne zusätzliche Konfiguration.
Weil die Werte als echte CSS-Custom-Properties vorliegen, lassen sie sich zur Laufzeit auch überschreiben, etwa für ein zweites Markenschema in einem Multi-Tenant-Setup oder für einen alternativen Dark-Mode-Farbsatz. Ein Generatorskript, das direkt den fertigen @theme-Block als Textdatei ausgibt, spart in der Praxis den manuellen Copy-Paste-Schritt und reduziert das Risiko, beim Uebertragen eine Stufe zu vertauschen oder einen Tippfehler in den Variablennamen einzubauen.
8. Kontrastprüfung und manuelle Nachjustierung
Eine algorithmisch generierte Skala ist ein sehr guter Ausgangspunkt, aber kein Freibrief, die Kontrastwerte ungeprüft zu übernehmen. Für Fließtext auf weißem Hintergrund verlangt WCAG AA ein Kontrastverhältnis von mindestens 4,5 zu 1, was bei den meisten generierten Skalen erst ab Stufe sechshundert oder siebenhundert zuverlässig erreicht wird. Jede Stufe, die im Projekt tatsächlich für Text verwendet werden soll, sollte deshalb einzeln mit einem Kontrastrechner gegen den geplanten Hintergrund geprüft werden, statt sich blind auf die Interpolation zu verlassen.
In der Praxis zeigt sich außerdem oft, dass die mittleren Stufen, insbesondere Vier- und Fünfhundert, nach der automatischen Berechnung etwas blass oder zu grau wirken, wenn die Ausgangsfarbe eine ungewöhnliche Kombination aus Hue und Chroma hat. Hier lohnt sich eine gezielte manuelle Nachjustierung dieser zwei bis drei Stufen per Hand, während der Rest der Skala unverändert aus dem Generator übernommen wird. Diese hybride Vorgehensweise, automatisch generieren und punktuell von Hand verfeinern, liefert in der Praxis die verlässlichsten Ergebnisse.
9. Häufige Fehler und Fazit für den eigenen Workflow
Der häufigste Fehler ist die lineare Interpolation in RGB oder HSL statt in OKLCH, weil sie an manchen Stellen der Skala sichtbare Helligkeitssprünge erzeugt, die im fertigen UI als leicht unruhig empfunden werden. Ein zweiter häufiger Fehler ist, die Chroma an den Rändern der Skala nicht zu reduzieren, wodurch der Browser Farben außerhalb des sRGB-Gamuts auf einen unerwünschten Ersatzwert clippt und die hellsten oder dunkelsten Stufen plötzlich anders wirken als geplant. Auch ein zu wenig dokumentiertes Skript, das niemand im Team nachvollziehen kann, wird schnell zum Problem, sobald eine zweite Markenfarbe für ein neues Projekt gebraucht wird.
Für den eigenen Workflow empfiehlt sich damit eine klare Reihenfolge: zunächst die Zielkurve für Lightness und Chroma anhand von Tailwinds eigenen Paletten grob festlegen, dann mit culori oder einem vergleichbaren Tool automatisch generieren, anschließend die Kontrastwerte für alle text-relevanten Stufen prüfen, und zuletzt die zwei oder drei kritischsten Stufen von Hand feinjustieren. Wer diesen Prozess einmal sauber aufsetzt, kann ihn für jede neue Markenfarbe in wenigen Minuten wiederholen, statt jedes Mal von vorn zu beginnen.
| Methode | Wahrnehmungsgleichmäßigkeit | Aufwand | Kontrolle über Ergebnis |
|---|---|---|---|
| HSL-Interpolation | Gering, sichtbare Helligkeitssprünge je nach Hue | Niedrig | Kaum steuerbar |
| OKLCH-Interpolation (Skript) | Hoch, folgt der Helligkeitswahrnehmung | Mittel, einmalige Skript-Erstellung | Vollständig über Kurve steuerbar |
| Fertiges Tool (uicolors.app) | Hoch, bereits OKLCH-basiert | Sehr niedrig | Eingeschränkt auf Tool-Optionen |
| Manuelles Design pro Stufe | Abhängig vom Designer | Sehr hoch | Maximal, aber zeitintensiv |
Mironsoft
Tailwind-CSS-Architektur, Design-Systeme und Performance
Tailwind-Frontends, die trotz tausender Utility-Klassen wartbar bleiben?
Wir prüfen bestehende Tailwind-Projekte auf aufgeblähte Klassenlisten, inkonsistente Design-Tokens und ungenutzte CSS-Reste und bauen daraus ein Design-System, das sich sauber skaliert statt mit jeder Komponente unübersichtlicher zu werden.
Design-System-Review
Tokens, Spacing-Skala und Komponentenkonsistenz auf Wartbarkeit prüfen.
Performance-Optimierung
CSS-Bundle-Größe, Purge-Konfiguration und Ladezeiten systematisch reduzieren.
Component-Architektur
Wiederverwendbare, gut strukturierte Komponenten statt Klassenlisten-Wildwuchs aufbauen.
10. Zusammenfassung
Farbpaletten aus einer Markenfarbe: Das Wichtigste auf einen Blick
Farbraum für Interpolation
OKLCH statt HSL, da der L-Kanal der tatsächlichen Helligkeitswahrnehmung folgt und keine hue-abhängigen Helligkeitssprünge entstehen.
Stufenanzahl
Elf Stufen von 50 bis 950, angelehnt an Tailwinds eigene Namenskonvention und Verwendungsabsicht je Stufe.
Werkzeuge
Eigenes Skript mit der Bibliothek culori für volle Kontrolle, alternativ fertige Generatoren wie uicolors.app oder Tailwind Shades.
Integration
Ausgabe direkt als CSS-Custom-Properties im @theme-Block von Tailwind v4, mit dem Präfix --color-brand-.