Zum Inhalt springen
Zurück zum Blog

Farben anpassen, ohne etwas kaputtzumachen

DesignCSS

Der übliche Weg, ein Tailwind-Projekt umzufärben, ist ein Suchen-und-Ersetzen über alle Dateien: bg-slate-900 wird zu bg-stone-900, text-slate-500 zu text-stone-500, und irgendeine Stelle vergisst man immer.

Hier gibt es diesen Weg nicht, weil in den Komponenten keine konkreten Farben stehen. Es gibt nur semantische Namen:

Utility Bedeutung
bg-bg Seitenhintergrund
bg-surface abgesetzte Fläche, z. B. eine Karte
bg-surface-strong betonte Fläche, Hover-Zustand
text-fg normaler Text
text-muted Nebentext
border-line Trennlinien und Rahmen
bg-brand / text-brand Akzentfarbe

Wo die Werte stehen

In src/styles/global.css, einmal für hell und einmal für dunkel:

:root {
  --ui-bg: oklch(99% 0.003 265);
  --ui-fg: oklch(21% 0.02 265);
  --ui-brand: oklch(55% 0.19 265);
}

.dark {
  --ui-bg: oklch(17% 0.015 265);
  --ui-fg: oklch(96% 0.008 265);
  --ui-brand: oklch(72% 0.15 265);
}

Die Notation ist oklch(Helligkeit Chroma Farbton). Der dritte Wert ist überall 265 – ein kühles Blau-Violett. Ersetz ihn durch 30 und die ganze Seite wird warm-orange, ohne dass die Kontraste kippen. Das ist der eigentliche Grund für OKLCH: Anders als bei HSL bleibt die wahrgenommene Helligkeit gleich, wenn du nur den Farbton drehst.

Die eine Zeile, die man übersieht

Weiter unten in derselben Datei werden die Variablen an Tailwind übergeben:

@theme inline {
  --color-bg: var(--ui-bg);
  --color-fg: var(--ui-fg);
}

Das inline ist wichtig. Ohne dieses Schlüsselwort löst Tailwind den Wert genau einmal auf :root auf – und der Dark Mode hätte keine Wirkung mehr, weil die Utility dann auf die helle Farbe festgenagelt wäre.

Neue Tokens hinzufügen

Drei Schritte, immer dieselben: Variable in :root anlegen, Gegenstück in .dark ergänzen, im @theme inline-Block durchreichen. Danach steht die neue Farbe als ganz normale Utility zur Verfügung – inklusive Autovervollständigung.

Die Akzentpalette

Neben der Markenfarbe gibt es sechs Akzente für Icons, Tags und Marker. Sie unterscheiden sich ausschließlich im Farbton – Helligkeit und Sättigung kommen aus zwei Variablen, die pro Theme einmal gesetzt sind:

--ui-accent-cyan: oklch(var(--accent-l) var(--accent-c) 215);
--ui-accent-pink: oklch(var(--accent-l) var(--accent-c) 350);

Das hat zwei angenehme Folgen. Erstens wirken alle Akzente gleich kräftig, statt dass einer heraussticht. Zweitens werden im Dark Mode alle sechs gleichzeitig heller und weicher, sobald du --accent-l und --accent-c unter .dark änderst. Zwölf Farbwerte, zwei Stellschrauben.

Eine Warnung: Gelb um Farbton 90 lässt sich bei mittlerer Helligkeit nicht sättigen – der Browser rechnet es in ein schlammiges Oliv um. Deshalb springt die Palette von Orange (45) direkt zu Grün (145).

Die fertig kombinierten Klassen stehen in src/lib/tones.ts und nicht in den Komponenten. Grund: Tailwind sucht im Quelltext nach vollständigen Klassennamen. Ein zusammengebautes bg-accent-${name} sieht es nicht, und die Farbe fehlte dann im Build – ohne Fehlermeldung.