Tutorials

CSS Relative Color Syntax: Farben dynamisch transformieren

8 Min. Lesezeit

CSS konnte Farben schon lange speichern, aber für ihre Manipulation war JavaScript, Sass-Funktionen oder ein Build-Schritt erforderlich. Die CSS Relative Color Syntax ändert das. Sie ermöglicht es, eine vorhandene Farbe – aus einer Variable, einem Keyword oder einem beliebigen Farbwert – zu nehmen und bestimmte Kanäle davon direkt in Ihrem Stylesheet zu transformieren. Sie können sie aufhellen, ihren Farbton verschieben, die Chroma reduzieren oder ihre Transparenz anpassen – alles in reinem CSS, zur Laufzeit.

Dieses Feature kam in Chrome 119, Firefox 128 und Safari 16.4, was es für die Produktion im Jahr 2026 ausreichend browserkompatibel macht. Es funktioniert mit jeder modernen CSS-Farbfunktion: rgb(), hsl(), oklch(), lab(), lch() und mehr.

Was ist die Relative Color Syntax?

Die Relative Color Syntax erweitert jede CSS-Farbfunktion mit einer from <color>-Klausel am Anfang. Das teilt dem Browser mit, die Ursprungsfarbe in ihre Kanäle zu zerlegen, und dann eine neue Farbe unter Verwendung dieser Kanäle zusammenzusetzen – möglicherweise mit Modifikationen.

Das grundlegendste Beispiel verwendet das from-Keyword, um eine Farbe unverändert durchzureichen:

/* Das ist ein No-op — erzeugt dieselbe Farbe wie die Eingabe */
color: oklch(from #3B82F6 l c h);

An sich nicht sehr nützlich, aber die eigentliche Kraft kommt, wenn Sie die extrahierten Kanalwerte modifizieren:

/* Aufhellen durch Erhöhen von L (Helligkeit) */
color: oklch(from #3B82F6 calc(l + 0.15) c h);

/* Farbton um 30 Grad verschieben */
color: oklch(from #3B82F6 l c calc(h + 30));

/* Entsättigen durch Reduzieren der Chroma */
color: oklch(from #3B82F6 l calc(c * 0.5) h);

/* Halbtransparent machen */
color: oklch(from #3B82F6 l c h / 0.5);

Jede dieser Transformationen verändert einen einzelnen Kanal, während die anderen intakt bleiben – etwas, das in reinem CSS ohne Präprozessor bisher unmöglich war.

Das from-Keyword

Das from-Keyword ist das syntaktische Herzstück der Relative Color Syntax. Es erscheint unmittelbar nach der öffnenden Klammer der Farbfunktion und vor den Kanalwerten:

color-function(from <origin-color> <channel1> <channel2> <channel3> [/ <alpha>])

Die <origin-color> kann ein beliebiger gültiger CSS-Farbwert sein:

/* Von einem Hex-Code */
oklch(from #FF5733 l c h)

/* Von einer benannten Farbe */
oklch(from tomato l c h)

/* Von einer CSS Custom Property */
oklch(from var(--brand-color) l c h)

/* Von einer anderen Farbfunktion */
oklch(from rgb(59, 130, 246) l c h)

/* Von currentColor */
oklch(from currentColor l c h)

Die Variante from currentColor ist besonders mächtig – sie erlaubt einer Komponente, die geerbte Textfarbe zu transformieren, ohne deren genauen Wert zu kennen.

Kanalnamen nach Farbfunktion

Jede Farbfunktion stellt ihre Kanäle nach dem from-Keyword unter spezifischen Namen bereit:

Funktion Kanal 1 Kanal 2 Kanal 3 Alpha
oklch() l c h alpha
oklab() l a b alpha
hsl() h s l alpha
rgb() r g b alpha
lab() l a b alpha
lch() l c h alpha

Beachten Sie, dass in hsl() die Kanal-Reihenfolge in der from-Zerlegung die Funktionssignatur widerspiegelt: h, s, l. In oklch() ist es l, c, h. Überprüfen Sie immer die Kanal-Reihenfolge für die verwendete Funktion.

Funktionsübergreifende Konvertierung

Die Ursprungsfarbe muss nicht zur Ausgabefunktion passen. Der Browser konvertiert automatisch:

/* Eingabe ist Hex, Ausgabe ist oklch — Browser konvertiert zuerst, dann zerlegt er */
oklch(from #FF5733 calc(l + 0.1) c h)

/* Eingabe ist hsl, Ausgabe ist rgb */
rgb(from hsl(200, 80%, 50%) calc(r * 0.9) g b)

Diese funktionsübergreifende Konvertierung bedeutet, dass Sie Ihre Design-Tokens in jedem Format speichern und Ausgaben in jedem Format erzeugen können, das Sie für die Manipulation bevorzugen.

Einzelne Kanäle anpassen

Die häufigsten Operationen an relativen Farben verwenden calc(), um extrahierte Kanalwerte zu modifizieren.

Helligkeitsanpassungen (OKLCH)

Mit OKLCH reicht der l-Kanal von 0 (Schwarz) bis 1 (Weiß). Das Addieren oder Subtrahieren eines festen Werts erzeugt ein vorhersehbar helleres oder dunkleres Ergebnis, weil OKLCH-Helligkeit wahrnehmungsgleichmäßig ist:

:root {
  --base: oklch(0.58 0.20 250);
}

.lighter  { color: oklch(from var(--base) calc(l + 0.15) c h); }
.lightest { color: oklch(from var(--base) calc(l + 0.30) c h); }
.darker   { color: oklch(from var(--base) calc(l - 0.15) c h); }
.darkest  { color: oklch(from var(--base) calc(l - 0.30) c h); }

Da OKLCH-Helligkeit wahrnehmungsmäßig kalibriert ist, erzeugt das Hinzufügen von 0,15 zu l einen gleich großen wahrgenommenen Helligkeitssprung, unabhängig vom Farbton – anders als bei HSL, wo dasselbe Inkrement je nachdem, ob die Farbe Gelb oder Blau ist, unterschiedlich aussieht.

Chroma-Anpassungen

Der c-Kanal steuert die Farbintensität. Ihn auf 0 zu setzen erzeugt ein neutrales Grau bei derselben Helligkeit. Ihn nach unten zu skalieren, entsättigt, ohne vollständig zu vergrauen:

/* Gedämpfte Variante — 50% weniger Chroma */
color: oklch(from var(--brand) l calc(c * 0.5) h);

/* Vollständig entsättigtes Grau bei derselben Helligkeit */
color: oklch(from var(--brand) l 0 h);

/* Lebhafter — 30% mehr Chroma (kann bei einigen Farbtönen den sRGB-Gamut verlassen) */
color: oklch(from var(--brand) l calc(c * 1.3) h);

Farbtonverschiebungen

Der h-Kanal ist ein Gradwert von 0 bis 360. Das Hinzufügen oder Subtrahieren verschiebt den Farbton auf dem Farbrad:

/* Komplementärfarbe — gegenüberliegende Seite des Rads */
color: oklch(from var(--brand) l c calc(h + 180));

/* Analoges +30° */
color: oklch(from var(--brand) l c calc(h + 30));

/* Analoges -30° */
color: oklch(from var(--brand) l c calc(h - 30));

Das Kombinieren mehrerer Kanalanpassungen erzeugt komplexe Transformationen in einer einzigen Deklaration:

/* Heller, gedämpfter und leicht anderer Farbton — eine tonale Variante */
color: oklch(from var(--brand) calc(l + 0.12) calc(c * 0.6) calc(h + 15));

Alphakanal

Verwenden Sie die Schrägstrich-Syntax, um Transparenz zu modifizieren:

/* 50%-Deckkraft-Version der Markenfarbe */
background: oklch(from var(--brand) l c h / 0.5);

/* Vollständig opake Version einer Farbe, die möglicherweise Transparenz hat */
color: oklch(from var(--text-muted) l c h / 1);

/* Vorhandenes Alpha skalieren — wenn Ursprung 0,8 Deckkraft hat, auf ~0,4 reduzieren */
background: oklch(from var(--overlay) l c h / calc(alpha * 0.5));

Töne und Schattierungen in reinem CSS erstellen

Der traditionelle Ansatz für Farbskalen erfordert die Vorberechnung jeder Schattierung und das Speichern als Variable. Mit der Relative Color Syntax können Sie eine gesamte Skala aus einer einzigen Basisvariable generieren:

:root {
  --primary: oklch(0.58 0.20 250);

  /* Skala — keine Vorberechnung notwendig */
  --primary-50:  oklch(from var(--primary) 0.97 calc(c * 0.1) h);
  --primary-100: oklch(from var(--primary) 0.94 calc(c * 0.2) h);
  --primary-200: oklch(from var(--primary) 0.88 calc(c * 0.4) h);
  --primary-300: oklch(from var(--primary) 0.78 calc(c * 0.6) h);
  --primary-400: oklch(from var(--primary) 0.68 calc(c * 0.8) h);
  --primary-500: var(--primary);
  --primary-600: oklch(from var(--primary) calc(l - 0.08) c h);
  --primary-700: oklch(from var(--primary) calc(l - 0.16) c h);
  --primary-800: oklch(from var(--primary) calc(l - 0.24) c h);
  --primary-900: oklch(from var(--primary) calc(l - 0.32) c h);
  --primary-950: oklch(from var(--primary) calc(l - 0.38) c h);
}

Ändern Sie --primary auf eine beliebige Farbe und die gesamte 11-Schritte-Skala wird automatisch im Browser neu generiert. Kein Build-Schritt, kein JavaScript, kein Sass.

Für Produktions-Design-Systeme, die sehr präzise Wahrnehmungsschritte erfordern, bietet der Schattengenerator handabgestimmte 50–950-Skalen. Der Relative-Color-Ansatz eignet sich ideal für kleinere Komponenten oder schnelles Prototyping, wo exakte Präzision weniger wichtig ist als Flexibilität.

Barrierefreie Töne für Hintergründe

Ein häufiges Muster ist das Erstellen sehr heller getönter Hintergründe für Benachrichtigungsbanner und Hinweisfelder:

:root {
  --success: oklch(0.65 0.20 145);  /* Ein lebhaftes Grün */
  --warning: oklch(0.75 0.18 70);   /* Ein warmes Amber */
  --danger:  oklch(0.62 0.24 25);   /* Ein kräftiges Rot */
}

.alert-success {
  background: oklch(from var(--success) 0.96 0.04 h);
  border-left: 3px solid var(--success);
  color: oklch(from var(--success) 0.30 0.14 h);
}

.alert-warning {
  background: oklch(from var(--warning) 0.97 0.04 h);
  border-left: 3px solid var(--warning);
  color: oklch(from var(--warning) 0.35 0.14 h);
}

.alert-danger {
  background: oklch(from var(--danger) 0.96 0.04 h);
  border-left: 3px solid var(--danger);
  color: oklch(from var(--danger) 0.32 0.14 h);
}

Der Hintergrund ist eine sehr helle, niedrig-chroma-Version der Alert-Farbe. Der Text verwendet eine sehr dunkle, mäßig gesättigte Version. Der Farbton (h) wird in allen Fällen von der Ursprungsfarbe beibehalten – alles bleibt automatisch farbtonkonsistent.

Reale Beispiele mit OKLCH

Theme-adaptive Hover-Zustände

.card {
  --card-accent: oklch(0.60 0.18 260);
  background: var(--card-accent);
  transition: background-color 150ms ease;
}

.card:hover {
  /* Beim Hover leicht abdunkeln — funktioniert unabhängig vom Akzent */
  background: oklch(from var(--card-accent) calc(l - 0.06) c h);
}

Dieses Muster ist besonders mächtig in Komponentenbibliotheken, wo die Akzentfarbe als Prop oder Custom Property übergeben wird. Der Hover-Zustand ist immer kontextuell angemessen, ohne separate Hover-Farben für jede Variante zu erfordern.

Text auf farbigen Hintergründen

.chip {
  --chip-color: oklch(0.62 0.20 260);

  /* Hintergrund: sehr heller Ton */
  background: oklch(from var(--chip-color) 0.94 0.06 h);

  /* Text: sehr dunkle Version desselben Farbtons */
  color: oklch(from var(--chip-color) 0.28 0.16 h);

  /* Rahmen: mittelleichte Version */
  border: 1px solid oklch(from var(--chip-color) 0.78 0.12 h);
}

Das erzeugt einen farbigen Chip, bei dem Hintergrund, Text und Rahmen harmonisch sind, weil sie denselben Farbton teilen. Ändern Sie --chip-color und der gesamte Satz wird aktualisiert.

Dunkelmodus-Anpassung mit from currentColor

.icon-wrapper {
  /* Icon-Farbe erbt vom Textkontext */
  color: var(--color-text-primary);
}

.icon-wrapper:hover {
  /* Leicht dunklere Version der aktuellen Farbe des Icons */
  color: oklch(from currentColor calc(l - 0.08) c h);
}

.icon-wrapper .background-glow {
  /* Halbtransparente Version der Icon-Farbe für einen Glüh-Effekt */
  background: oklch(from currentColor l c h / 0.15);
}

Der currentColor-Ursprung bedeutet, dass diese Komponente in jedem Textkontextfarbe korrekt funktioniert, einschließlich Dark Mode, ohne den spezifischen Farbwert kennen zu müssen.

Komplementären Akzent generieren

Für Designs, die eine komplementäre Akzentfarbe aus der primären Markenfarbe benötigen:

:root {
  --brand: oklch(0.60 0.20 250);   /* Blau */

  /* Komplement: entgegengesetzter Farbton, gleiche Helligkeit und Chroma */
  --accent: oklch(from var(--brand) l c calc(h + 180));
  /* Ergebnis: ungefähr Orange bei Farbton ~70° */

  /* Weicheres Komplement für Hintergründe */
  --accent-bg: oklch(from var(--brand) 0.95 0.06 calc(h + 180));
}

Das erzeugt eine mathematisch komplementäre Farbe. Für ein ausgefeilteres Split-Komplementär-Schema versetzen Sie um ±150° oder ±160° statt 180°.

Browser-Unterstützung und Fallbacks

Die Relative Color Syntax wird unterstützt in:

  • Chrome/Edge: seit Version 119 (November 2023)
  • Firefox: seit Version 128 (Juli 2024)
  • Safari: seit Version 16.4 (März 2023) — Safari war der erste

Die globale Unterstützung liegt Anfang 2026 bei etwa 85–88%. Für breitere Abdeckung geben Sie Fallbacks an:

.btn-hover {
  /* Fallback: vorberechneter Hex für ältere Browser */
  background-color: #1D4ED8;
}

@supports (color: oklch(from red l c h)) {
  .btn-hover {
    /* Modern: dynamisch aus der Basis abgeleitet */
    background-color: oklch(from var(--btn-bg) calc(l - 0.08) c h);
  }
}

Der @supports-Test (color: oklch(from red l c h)) prüft speziell auf Unterstützung der Relative Color Syntax, nicht nur auf OKLCH-Unterstützung, was wichtig ist, da OKLCH und Relative Color Syntax in verschiedenen Browser-Versionen ausgeliefert wurden.

Wesentliche Erkenntnisse

  • Die Relative Color Syntax verwendet from <origin-color> innerhalb einer beliebigen CSS-Farbfunktion, um diese Farbe in ihre Kanäle zu zerlegen, die dann mit calc() modifiziert und in eine neue Farbe zusammengesetzt werden können.
  • OKLCH ist die beste Funktion für die Relative-Color-Manipulation, weil ihre Kanäle (Helligkeit, Chroma, Farbton) eng auf die Design-Intention abbilden und die Helligkeit wahrnehmungsgleichmäßig ist – gleiche Inkremente erzeugen gleich aussehende Änderungen.
  • Sie können jeden einzelnen Kanal unabhängig anpassen: l addieren zum Aufhellen, c multiplizieren zum Entsättigen, h addieren zum Farbtonverschieben, oder alpha modifizieren zum Ändern der Transparenz.
  • Der from currentColor-Ursprung erstellt selbst-adaptierende Komponenten, die ihre Farben aus der geerbten Textfarbe ableiten und sie so in jedem Kontext einschließlich Dark Mode automatisch korrekt machen.
  • Die Browser-Unterstützung umfasst alle modernen Browser seit Ende 2023 / Mitte 2024. Verwenden Sie @supports (color: oklch(from red l c h)), um speziell auf die Relative Color Syntax zu testen.
  • Verwenden Sie den Schattengenerator für präzise, handabgestimmte 50–950-Skalen in Produktions-Design-Systemen. Verwenden Sie die Relative Color Syntax für dynamische, laufzeit-abgeleitete Varianten in Komponenten.
  • Verwenden Sie den Farbkonverter, um Ihre bestehenden Hex-Markenfarben in OKLCH-Werte zu übersetzen und ihre l-, c- und h-Kanäle zu verstehen, bevor Sie Relative-Color-Ausdrücke schreiben.

Ähnliche Farben

Ähnliche Marken

Ähnliche Werkzeuge