Relative Color Syntax praktisch nutzen: Farbtöne aus CSS-Variablen ableiten
{ }
@
CSS · Farbe · Design Tokens · Color Level 5
Relative Color Syntax praktisch nutzen
Farbtöne direkt aus vorhandenen CSS-Variablen ableiten

Die Relative Color Syntax erlaubt es, aus einer einzigen Markenfarbe im Browser eine vollständige Palette zu berechnen, statt Hover, Active und Rahmenfarben als eigene Variablen zu pflegen. Mit dem Schlüsselwort from, Farbraum-Kanälen und calc() entstehen wartbare Farbsysteme direkt in nativem CSS, ganz ohne Sass oder Build-Schritt.

18 Min. Lesezeit from · oklch · calc() · Custom Properties Chrome 119+ · Safari 16.4+ · Firefox 128+

1. Was Relative Color Syntax löst

Die Relative Color Syntax ist Teil des CSS Color Module Level 5 und beantwortet ein Problem, das in jedem größeren Stylesheet auftaucht: Aus einer definierten Basisfarbe müssen Varianten für Hover, Active, Fokus-Ringe und Rahmen entstehen, ohne dass jede Variante als eigene Custom Property gepflegt werden muss. Vor der Relative Color Syntax gab es dafür nur zwei Wege, entweder einen Präprozessor wie Sass mit Funktionen wie darken() und lighten() einzusetzen, oder für jede Variante eine eigene Hex- oder OKLCH-Variable von Hand zu berechnen und zu pflegen.

Beide Wege erzeugen Wartungsaufwand. Ändert sich die Markenfarbe, müssen bei der manuellen Variante alle abgeleiteten Werte neu berechnet werden. Bei Sass entsteht zusätzlich ein Build-Schritt, der zur Laufzeit im Browser nicht mehr veränderbar ist, was Theming per JavaScript oder per prefers-color-scheme erschwert. Die Relative Color Syntax löst genau das: Die Ableitung passiert direkt im Browser, zur Laufzeit, aus dem aktuellen Wert einer beliebigen Farbe, egal ob sie als Custom Property, als Literal oder als Ergebnis einer weiteren Farbfunktion vorliegt.

2. Syntax im Detail: from, Kanäle und calc()

Die Grundform der Relative Color Syntax sieht so aus: oklch(from <farbe> l c h). Das Schlüsselwort from gefolgt von einer beliebigen Farbe öffnet den Zugriff auf deren Kanäle im Zielfarbraum. Bei oklch() sind das l für Lightness, c für Chroma und h für Hue, jeweils unter demselben Namen wie im Funktionsaufruf ansprechbar. Wird ein Kanal unverändert übernommen, schreibt man einfach seinen Namen, soll er verändert werden, ersetzt man ihn durch einen berechneten Ausdruck oder direkt durch calc().

Wichtig ist, dass die Quellfarbe in jedem beliebigen Format vorliegen darf, etwa als Hex-Wert, als rgb(), als hsl() oder als weitere Relative Color Syntax-Berechnung, während der Zielfarbraum in der äußeren Funktion bestimmt, mit welchen Kanalnamen gearbeitet wird. Das erlaubt sogar Farbraum-Konvertierung als Nebeneffekt, aus einer als Hex definierten Farbe können mit oklch(from #7c3aed l c h) direkt deren OKLCH-Kanäle gelesen werden, ganz ohne externes Konvertierungstool.


/* Basic Relative Color Syntax: read channels from an existing color */
:root {
  --brand: #7c3aed;
}

.button {
  /* Convert hex to oklch and read its channels directly */
  background: oklch(from var(--brand) l c h);
}

.button:hover {
  /* Reduce lightness by an absolute amount using calc() */
  background: oklch(from var(--brand) calc(l - 0.08) c h);
}

.button:active {
  /* Reduce lightness further, slightly desaturate too */
  background: oklch(from var(--brand) calc(l - 0.14) calc(c * 0.9) h);
}

Ein häufiger Stolperstein bei diesem Muster: l in oklch() ist auf den Bereich 0 bis 1 normiert, während manche Tools Lightness als Prozentwert von 0 bis 100 ausgeben. Wer mit calc(l - 8%) rechnet, statt mit calc(l - 0.08), erhält ein völlig anderes Ergebnis oder einen ungültigen Wert. Die Relative Color Syntax unterstützt zwar auch Prozentangaben für l, c und h in manchen Kontexten, konsistent und vorhersehbar bleibt aber nur, wer sich pro Farbraum an eine Einheit hält und diese im Team dokumentiert.

3. Hover und Active Zustände aus einer Basisfarbe ableiten

Der häufigste praktische Einsatz der Relative Color Syntax ist genau das Beispiel aus dem letzten Abschnitt: interaktive Zustände einer Komponente aus ihrer Basisfarbe ableiten. Statt für jeden Button drei bis vier Variablen zu pflegen, reicht eine einzige Custom Property, aus der Hover, Active, Fokus und Disabled berechnet werden. Das reduziert nicht nur die Anzahl der Variablen, sondern garantiert auch, dass alle Zustände tatsächlich zur Basisfarbe passen, weil sie mathematisch aus ihr abgeleitet sind, statt unabhängig von Hand gepflegt zu werden.

Besonders wertvoll wird das in Komponenten-Bibliotheken mit vielen Farbvarianten, etwa einem Button, der als primary, danger, success oder warning existiert. Statt für jede Variante ein komplettes Set an Zustandsfarben zu definieren, definiert man nur die Basisfarbe pro Variante und lässt alle Zustände über dieselbe Relative Color Syntax-Formel berechnen. Ändert sich später der gewünschte Kontrast für Hover-Zustände insgesamt, genügt eine Anpassung der Formel an einer zentralen Stelle, statt Dutzende Einzelwerte zu korrigieren.

4. Kombination mit oklch für gleichmäßige Abstufungen

Die Relative Color Syntax entfaltet ihr volles Potenzial in Kombination mit dem oklch()-Farbraum, weil dessen Lightness-Achse wahrnehmungsgleichmäßig ist. Eine Reduktion von l um denselben Betrag wirkt bei jeder Ausgangsfarbe gleich stark dunkler, unabhängig davon, ob die Basisfarbe Blau, Gelb oder Violett ist. Bei hsl() ist das nicht der Fall, dort erzeugt dieselbe Lightness-Reduktion je nach Farbton unterschiedlich stark wahrgenommene Helligkeitsunterschiede, weil hsl() nicht auf menschlicher Farbwahrnehmung, sondern auf einem einfachen zylindrischen RGB-Modell basiert.

In der Praxis bedeutet das: Eine mit Relative Color Syntax und oklch() gebaute Abstufungsformel funktioniert für jede beliebige Markenfarbe gleich gut, ohne dass für jede Farbe individuell nachjustiert werden muss. Das ist der entscheidende Vorteil gegenüber älteren Sass-Funktionen wie darken(), die intern häufig auf hsl() aufbauen und deshalb bei manchen Farbtönen zu unerwartet starken oder schwachen Kontrasten führen.


/* Perceptually uniform tint and shade scale from one base color */
:root {
  --brand-500: oklch(58% 0.19 291);
}

.card {
  /* Consistent lightness steps regardless of hue */
  --brand-100: oklch(from var(--brand-500) 0.94 calc(c * 0.35) h);
  --brand-300: oklch(from var(--brand-500) 0.80 calc(c * 0.7) h);
  --brand-700: oklch(from var(--brand-500) calc(l - 0.16) c h);
  --brand-900: oklch(from var(--brand-500) calc(l - 0.32) calc(c * 0.6) h);

  background: var(--brand-100);
  border: 1px solid var(--brand-300);
  color: var(--brand-900);
}

5. Alpha-Kanal-Manipulation ohne zusätzliche Variable

Neben Lightness, Chroma und Hue erlaubt die Relative Color Syntax auch den direkten Zugriff auf den Alpha-Kanal über den Namen alpha. Das macht es überflüssig, für transparente Varianten einer Farbe eine zweite Custom Property in rgba- oder Farbfunktions-Notation zu pflegen. Statt --brand-transparent: rgba(124, 58, 237, 0.15) als eigene, potenziell aus dem Sync geratene Variable zu definieren, berechnet man den transparenten Wert direkt aus der Basisfarbe.

Das ist besonders nützlich für Overlay-Hintergründe, Fokus-Ringe und subtile Trennlinien, die alle denselben Farbton wie die Basisfarbe tragen sollen, aber mit unterschiedlicher Deckkraft. Mit der Relative Color Syntax bleibt die Beziehung zwischen Basisfarbe und ihren transparenten Varianten immer explizit im Code sichtbar, statt implizit über zwei unabhängig gepflegte Variablen zu bestehen, die bei einer Änderung der Basisfarbe leicht auseinanderlaufen.


/* Alpha channel access via Relative Color Syntax */
:root {
  --focus-color: oklch(62% 0.21 264);
}

.input:focus-visible {
  outline: 2px solid var(--focus-color);
  /* Same hue, reduced opacity, no second variable required */
  box-shadow: 0 0 0 4px oklch(from var(--focus-color) l c h / 0.25);
}

.overlay {
  /* Derive a translucent backdrop directly from the brand color */
  background: oklch(from var(--brand-500) calc(l - 0.4) c h / 0.55);
}

6. Praxisbeispiel: komplette Palette aus einer Markenfarbe

In einem realen Design-System-Projekt lässt sich die Relative Color Syntax nutzen, um aus genau einer Markenfarbe eine zehnstufige Palette zu erzeugen, ähnlich den Skalen von Tailwind CSS, aber ohne vorab generierte statische Werte. Der Vorteil gegenüber einer fest im Buildprozess erzeugten Palette: Ändert sich die Markenfarbe während eines Rebrandings, muss lediglich die eine Basisvariable angepasst werden, alle abgeleiteten Stufen aktualisieren sich automatisch, ganz ohne erneuten Build.

Diese Technik eignet sich hervorragend für Multi-Tenant-Anwendungen, in denen jeder Kunde seine eigene Markenfarbe hinterlegt. Statt für jeden Kunden eine komplette Palette zu berechnen und als CSS-Datei auszuliefern, genügt eine einzige Custom Property pro Tenant plus eine gemeinsam genutzte Relative Color Syntax-Formel, die für jeden Tenant automatisch die passenden Abstufungen erzeugt.


/* Ten-step palette derived from a single tenant brand color */
:root {
  --tenant-brand: oklch(55% 0.20 258);

  --color-50:  oklch(from var(--tenant-brand) 0.97 calc(c * 0.15) h);
  --color-100: oklch(from var(--tenant-brand) 0.93 calc(c * 0.3)  h);
  --color-300: oklch(from var(--tenant-brand) 0.82 calc(c * 0.65) h);
  --color-500: var(--tenant-brand);
  --color-700: oklch(from var(--tenant-brand) calc(l - 0.14) c h);
  --color-900: oklch(from var(--tenant-brand) calc(l - 0.30) calc(c * 0.7) h);
}

7. Browser-Unterstützung, Fallbacks und @supports

Chrome, Edge und Safari unterstützen die Relative Color Syntax seit 2023 beziehungsweise 2024 vollständig, Firefox zog mit Version 128 nach. Für Projekte, die noch ältere Browser bedienen müssen, empfiehlt sich ein Fallback über @supports, bei dem außerhalb des unterstützten Blocks feste Hex- oder OKLCH-Werte als statische Reserve dienen. Wichtig dabei: @supports (color: oklch(from red l c h)) prüft konkret die Relative-Color-Syntax-Fähigkeit, nicht nur die generelle oklch()-Unterstützung, da manche Browser oklch() ohne from bereits früher implementiert hatten.

In der Praxis reicht dieser Fallback meist aus: Alte Browser sehen eine solide, manuell gepflegte Basispalette, moderne Browser bekommen die dynamisch berechnete Version mit allen Vorteilen der Relative Color Syntax. Da Farbabstufungen selten geschäftskritisch sind, ist ein optisch leicht abweichender, aber funktional korrekter Fallback in den allermeisten Projekten ein akzeptabler Kompromiss.


/* Fallback for browsers without Relative Color Syntax support */
.button {
  background: #6d28d9; /* static fallback shade */
}

@supports (color: oklch(from red l c h)) {
  .button {
    background: oklch(from var(--brand-500) l c h);
  }

  .button:hover {
    background: oklch(from var(--brand-500) calc(l - 0.08) c h);
  }
}

8. Wartbarkeit im Vergleich zu Sass-Funktionen

Sass-Funktionen wie darken(), lighten() und mix() galten jahrelang als Standardlösung für abgeleitete Farben, haben aber einen strukturellen Nachteil: Sie werden zur Build-Zeit ausgewertet und erzeugen statische Werte im ausgelieferten CSS. Ein Theme-Wechsel zur Laufzeit, etwa über prefers-color-scheme oder einen manuellen Dark-Mode-Toggle, kann diese Werte nicht mehr beeinflussen, weil sie bereits fest im Stylesheet stehen. Die Relative Color Syntax löst genau dieses Problem, weil die Berechnung im Browser passiert und automatisch neu ausgewertet wird, sobald sich die referenzierte Custom Property ändert.

Ein weiterer Vorteil: Mit der Relative Color Syntax entfällt die Abhängigkeit von einem Build-Tool für reine Farbberechnungen. Kleinere Projekte ohne Sass-Toolchain profitieren besonders, weil sie dieselbe Funktionalität nun in reinem CSS erreichen, ohne node-sass, Dart Sass oder einen zusätzlichen PostCSS-Schritt einzuführen. Für Design-Systeme, die ohnehin auf Custom Properties setzen, ist die Relative Color Syntax damit die konsequente native Weiterentwicklung.

9. Relative Color Syntax im direkten Vergleich

Die folgende Tabelle stellt die drei gängigen Ansätze zur Farbableitung gegenüber und zeigt, wann welcher Ansatz die bessere Wahl ist.

Kriterium Sass darken/lighten Relative Color Syntax Manuelle Variablen
Laufzeit-Update Nein, statisch Ja, live im Browser Nein, manuell
Build-Schritt nötig Ja Nein Nein
Wahrnehmungsgleichmäßig Selten (hsl-basiert) Ja, mit oklch Abhängig vom Ersteller
Anzahl Variablen Gering Minimal Hoch
Browser-Support 2026 Nicht relevant (Build-Zeit) Alle modernen Engines Universell

In neuen Projekten mit modernem Browser-Ziel ist die Relative Color Syntax fast immer die richtige Wahl, weil sie Build-Abhängigkeiten reduziert und gleichzeitig Laufzeit-Theming ermöglicht. Bestehende Projekte mit ausgereifter Sass-Toolchain müssen nicht sofort migrieren, sollten aber neue Farbfunktionen bevorzugt mit der Relative Color Syntax aufbauen, um schrittweise unabhängiger von der Build-Zeit-Berechnung zu werden.

Mironsoft

CSS-Architektur, Design Tokens und moderne Farbsysteme

Eine Farbpalette, die sich selbst pflegt?

Wir bauen Farbsysteme mit Relative Color Syntax und oklch, die aus einer einzigen Markenfarbe pro Tenant automatisch konsistente, wahrnehmungsgleichmäßige Paletten ableiten, ganz ohne Build-Schritt und ohne doppelte Wartung.

Farbsystem-Audit

Bestehende Variablen und Sass-Funktionen auf Relative Color Syntax migrieren

Design Tokens

Skalierbare Token-Architektur mit oklch und Relative Color Syntax aufbauen

Multi-Tenant-Theming

Pro Kunde nur eine Basisfarbe, alle Abstufungen automatisch berechnet

10. Zusammenfassung

Die Relative Color Syntax verändert, wie Farbsysteme in CSS aufgebaut werden. Statt für jede Variante einer Farbe eine eigene Custom Property zu pflegen, wird aus einer einzigen Basisfarbe mit from, Farbraum-Kanälen und calc() alles Weitere zur Laufzeit im Browser berechnet. Kombiniert mit oklch() entstehen wahrnehmungsgleichmäßige Abstufungen, die für jede Markenfarbe gleich gut funktionieren, ohne manuelles Nachjustieren pro Farbton.

Der größte praktische Gewinn zeigt sich in Design-Systemen und Multi-Tenant-Anwendungen, wo aus einer einzigen Variable pro Marke automatisch komplette Paletten inklusive Hover-, Active- und transparenten Zuständen entstehen. Mit einem @supports-Fallback lässt sich die Relative Color Syntax bereits heute produktiv einsetzen, während ältere Browser eine statische Reservefarbe erhalten.

Relative Color Syntax praktisch nutzen — Das Wichtigste auf einen Blick

Grundsyntax

oklch(from var(--brand) l c h) liest Kanäle einer beliebigen Farbe aus und erlaubt gezielte Anpassung einzelner Werte.

Mit oklch kombinieren

Wahrnehmungsgleichmäßige Lightness-Achse macht Abstufungsformeln unabhängig vom konkreten Farbton.

Alpha-Kanal

Transparente Varianten direkt aus der Basisfarbe ableiten, ohne zweite Variable in rgba-Notation.

Fallback

@supports (color: oklch(from red l c h)) liefert alten Browsern eine statische Reservefarbe.

11. FAQ: Relative Color Syntax praktisch nutzen

1Was ist die Relative Color Syntax?
Ein Feature aus CSS Color Level 5, das mit from erlaubt, Kanäle einer bestehenden Farbe zu lesen und gezielt mit calc() zu verändern.
2Besser als Sass darken/lighten?
Sass erzeugt statische Build-Zeit-Werte. Die Relative Color Syntax rechnet live im Browser und reagiert auf Änderungen der Custom Property.
3Welche Einheit hat l bei calc()?
Auf 0 bis 1 normiert. calc(l - 0.08) senkt die Helligkeit um acht Hundertstel, nicht acht Prozentpunkte.
4Funktioniert es mit hsl oder rgb?
Ja, jeder Zielfarbraum ist erlaubt. oklch wird wegen der wahrnehmungsgleichmäßigen Achse für Abstufungen empfohlen.
5Wie prüfe ich die Unterstützung?
@supports (color: oklch(from red l c h)) prüft gezielt die Relative-Color-Syntax-Fähigkeit, nicht nur oklch generell.
6Transparente Varianten möglich?
Ja, über alpha im Ausdruck, etwa l c h / 0.25, ganz ohne zweite Variable in rgba-Notation.
7Gut für Multi-Tenant-Theming?
Sehr gut, eine Basisvariable pro Tenant genügt, alle Abstufungen berechnen sich automatisch aus einer gemeinsamen Formel.
8Ersetzt es color-mix vollständig?
Nein, color-mix mischt zwei Farben, die Relative Color Syntax verändert Kanäle einer einzigen Farbe. Beide ergänzen sich oft.
9Muss ich Sass entfernen?
Nein, ein schrittweiser Umstieg reicht. Neue Farbfunktionen nativ aufbauen, bestehende Sass-Berechnungen laufen parallel weiter.
10Welche Browser unterstützen es 2026?
Chrome, Edge und Safari vollständig seit 2023/2024, Firefox seit Version 128. Fallback über @supports für ältere Versionen.