CSS · Farbraum · oklch · Color Level 4
CSS oklch() Farbraum
Wahrnehmungsgleichmäßigkeit, P3-Gamut und bessere Farbverläufe

oklch() ist der modernste Farbraum in CSS Color Level 4 und löst fundamentale Probleme von hsl() und rgb(): Die Helligkeitsachse ist wahrnehmungsgleichmäßig, Farbverläufe durchqueren keine entsättigten Grautöne, und der Zugang zum P3-Display-Gamut ermöglicht lebhaftere Farben auf modernen Bildschirmen — direkt im Browser, ohne Bildbearbeitungssoftware.

13 Min. Lesezeit oklch · P3 · color-gamut · oklch vs. hsl · Design Tokens Chrome 111+ · Firefox 113+ · Safari 15.4+ · 2026

1. Warum hsl() und rgb() an Grenzen stoßen

Die CSS-Farbfunktionen hsl() und rgb() sind seit Jahrzehnten Standard im Web und haben fundamentale Schwächen, die erst durch den Vergleich mit modernen Farbräumen wie dem CSS oklch() Farbraum offensichtlich werden. Das größte Problem von hsl(): Die Helligkeit (L) ist nicht wahrnehmungsgleichmäßig. Zwei Farben mit identischem L-Wert in hsl() erscheinen dem menschlichen Auge unterschiedlich hell, weil das menschliche Sehsystem Farben verschiedener Wellenlängen unterschiedlich hell wahrnimmt. Ein blau-lila Farbton bei hsl(260, 100%, 50%) wirkt deutlich dunkler als ein gelb-grüner Farbton bei hsl(90, 100%, 50%), obwohl beide denselben Helligkeitswert haben.

Das zweite Problem: Der sRGB-Farbraum, in dem hsl() und rgb() operieren, deckt nur einen Teil der Farben ab, die moderne Displays anzeigen können. Displays mit P3-Gamut (alle iPhones seit 2016, alle neueren MacBooks, viele Android-Flaggschiffe) können gesättigtere, lebhaftere Farben darstellen als sRGB erlaubt. Mit hsl() und rgb() sind diese Farben schlicht nicht erreichbar. Der CSS oklch() Farbraum löst beide Probleme gleichzeitig: wahrnehmungsgleichmäßige Achsen und Zugang zu Farben außerhalb des sRGB-Gamuts.

2. oklch() Grundlagen: L, C und H erklärt

Die Funktion CSS oklch() nimmt drei Parameter: L (Lightness, Helligkeit), C (Chroma, Sättigung) und H (Hue, Farbton). Die Helligkeit L reicht von 0 (schwarz) bis 1 (weiß), mit 0,5 als mittleres Grau. Das Besondere: Diese Helligkeitsachse ist wahrnehmungsgleichmäßig kalibriert. Blau bei oklch(0.5 0.2 260) und Gelb bei oklch(0.5 0.15 90) erscheinen dem menschlichen Auge tatsächlich gleich hell – das ist in hsl() nicht der Fall.

Der Chroma-Wert C im CSS oklch() Farbraum ist unbegrenzt – theoretisch kann jede positive Zahl angegeben werden. Praktisch liegen die meisten sRGB-Farben im Bereich 0 bis 0,37. P3-Farben können bis etwa 0,37–0,45 reichen. Werte darüber werden vom Browser auf den darstellbaren Gamut des Displays geclippt. Das bedeutet: Man kann eine Farbe mit oklch(0.7 0.5 290) definieren und der Browser stellt die gesättigteste Version dar, die das Display unterstützt – auf einem P3-Display lebhafter als auf einem sRGB-Display. Der Farbton H folgt demselben 0–360-Grad-Prinzip wie hsl(), aber die Farbverteilung auf dem Kreis ist gleichmäßiger perzeptuell.


/* CSS oklch() color function — L C H syntax */
:root {
  /* oklch(lightness chroma hue) */
  --color-primary:       oklch(0.55 0.22 290);   /* vivid purple */
  --color-primary-light: oklch(0.80 0.14 290);   /* light purple */
  --color-primary-dark:  oklch(0.35 0.20 290);   /* dark purple */

  /* Perceptually uniform steps — each step feels equally different */
  --blue-100: oklch(0.95 0.05 260);
  --blue-300: oklch(0.80 0.10 260);
  --blue-500: oklch(0.60 0.18 260);
  --blue-700: oklch(0.40 0.15 260);
  --blue-900: oklch(0.20 0.08 260);

  /* Alpha channel — oklch with alpha */
  --overlay: oklch(0.10 0.05 290 / 0.6);

  /* Wide-gamut P3 color (exceeds sRGB) */
  --accent-vivid: oklch(0.65 0.35 150);  /* vivid green, P3-only */
}

.button-primary {
  background: var(--color-primary);
  color: oklch(0.98 0.01 290);
}

.button-primary:hover {
  background: var(--color-primary-dark);
}

3. Wahrnehmungsgleichmäßigkeit: was das bedeutet

Wahrnehmungsgleichmäßigkeit (perceptual uniformity) ist die zentrale Eigenschaft des CSS oklch() Farbraums. Sie bedeutet, dass gleiche numerische Abstände auf der Helligkeitsachse auch gleich großen wahrgenommenen Unterschieden im Auge des Betrachters entsprechen. Das ist eine mathematisch präzise Kalibrierung des Farbraums an das menschliche Sehsystem – und sie macht den Unterschied bei jedem praktischen Einsatz von Farben spürbar. Wenn ein Design-System eine Farbpalette definiert – blau-100, blau-200, bis blau-900 – dann sollen die Helligkeitsstufen gleichmäßig wirken. Mit hsl() scheitert das bei bestimmten Farbtönen systematisch, mit CSS oklch() funktioniert es konsistent.

Ein konkretes Beispiel für die Auswirkung der Wahrnehmungsgleichmäßigkeit: Kontrast-Berechnungen für Accessibility. Um WCAG-konforme Farbkontraste sicherzustellen, muss die wahrgenommene Helligkeit zweier Farben gemessen werden. Berechnungen auf Basis des CSS oklch() Farbraums sind präziser als Berechnungen auf Basis von sRGB, weil die Lightness-Achse bereits wahrnehmungskorrigiert ist. Design-Tokens, die auf CSS oklch() basieren, erzeugen konsistentere Kontrastverhältnisse über verschiedene Farbtöne hinweg – ein klarer Vorteil für barrierefreies Design.

4. P3-Gamut: lebhaftere Farben auf modernen Displays

Der P3-Farbraum (Display P3) deckt etwa 25 Prozent mehr Farben ab als sRGB. Das sind vor allem gesättigtere Grüntöne, leuchtstärkere Orangetöne und intensivere Rottöne, die auf sRGB-Displays nicht darstellbar sind. Auf einem iPhone, einem neueren MacBook oder einem modernen Android-Flaggschiff mit P3-Display sehen diese Farben deutlich lebhafter aus als dieselben Farben in sRGB. Mit dem CSS oklch() Farbraum können diese P3-Farben direkt in CSS definiert werden, indem der Chroma-Wert über den sRGB-Bereich hinaus erhöht wird.

Der Browser handhabt das automatisch korrekt: Auf einem P3-Display werden die lebhafteren Farben angezeigt. Auf einem sRGB-Display werden die Farben auf den darstellbaren sRGB-Gamut geclippt – das Clipping erfolgt dabei möglichst farbnah, so dass die Absicht der Farbe erhalten bleibt. Das bedeutet: Es ist sicher, P3-Farben in CSS oklch() zu definieren, auch wenn nicht alle Nutzer P3-Displays haben. Die sRGB-Nutzer sehen die gesättigtste sRGB-Entsprechung, P3-Nutzer sehen die volle Leuchtkraft. Für bewusste Kontrolle über den Fallback empfiehlt sich die color-gamut Media Query.


/* Wide-gamut colors with oklch — P3 gamut access */

/* sRGB-safe oklch color (C < 0.37 for most hues) */
.badge-safe {
  background: oklch(0.55 0.25 290);  /* vivid purple, sRGB-compatible */
  color: oklch(0.98 0.01 290);
}

/* Wide-gamut P3 color — more vivid on P3 displays */
.badge-vivid {
  background: oklch(0.55 0.40 150);  /* vivid green, P3 only */
}

/* Explicit P3 gamut control with color() function */
.hero-gradient {
  background: linear-gradient(
    135deg,
    oklch(0.40 0.25 290),   /* dark purple */
    oklch(0.75 0.35 150)    /* vivid green — P3 extended */
  );
}

/* CSS color() function for explicit color space */
.p3-accent {
  /* display-p3 color space — explicit */
  background: color(display-p3 0.2 0.8 0.4);
}

/* Fallback for sRGB displays using @supports */
@supports not (background: oklch(0 0 0)) {
  .badge-vivid {
    background: hsl(150, 60%, 45%);  /* sRGB approximation */
  }
}

5. Farbverläufe mit oklch(): keine grauen Mittelpunkte

Einer der sichtbarsten Vorteile des CSS oklch() Farbraums sind Farbverläufe zwischen zwei gesättigten Farben. In hsl() und rgb() führen Verläufe zwischen komplementären Farben (z.B. Blau und Orange) durch einen entsättigten, grauen Mittelpunkt – weil sich die RGB-Kanäle in der Mitte geometrisch zu einem Grauton mitteln. Im CSS oklch() Farbraum bleibt die Sättigung entlang des Verlaufs erhalten. Der Übergang von Blau zu Orange in oklch() führt durch gesättigte Zwischentöne – typischerweise über Grün oder Lila, je nach Richtung – und wirkt dadurch lebendiger und professioneller als dasselbe Gradient in sRGB.

CSS unterstützt ab Level 4 die Angabe des Farbraums für Gradienten direkt in der Funktion: linear-gradient(in oklch, color1, color2). Damit wird der Browser angewiesen, den Verlauf im CSS oklch() Farbraum zu interpolieren statt im sRGB-Standardraum. Das ist einer der wenigen Fälle, in denen der Interpolations-Farbraum explizit gesteuert werden muss – standardmäßig interpoliert der Browser Gradienten in sRGB, selbst wenn die definierten Farben in oklch() angegeben sind.

6. Design Tokens mit oklch() und Custom Properties

Die Kombination aus CSS oklch() und Custom Properties ist der modernste Ansatz für Design-Token-Systeme in CSS. Statt feste Hex-Werte oder hsl()-Werte als Custom Properties zu definieren, werden die drei Achsen von CSS oklch() als separate Custom Properties gespeichert: --brand-l: 0.55, --brand-c: 0.22, --brand-h: 290. Die eigentliche Farbfunktion kombiniert diese Achsen dann zu einer Farbe. Das erlaubt, einzelne Achsen per JavaScript oder in Media Queries anzupassen, ohne die gesamte Farbe neu definieren zu müssen.

Für Dark-Mode-Implementierungen ist dieser Ansatz besonders elegant: Statt für jeden Dark-Mode-Farbton separate Custom Properties zu definieren, kann die Helligkeit --brand-l einfach erhöht werden. oklch(var(--brand-l) var(--brand-c) var(--brand-h)) reagiert dann automatisch korrekt auf die Helligkeitsanpassung. Das funktioniert mit CSS oklch() deutlich besser als mit hsl(), weil die wahrnehmungsgleichmäßige Helligkeitsachse sicherstellt, dass alle Farbtöne im Dark Mode gleich hell wirken – und nicht wie im hsl()-Fall einige Farbtöne bei derselben Helligkeit viel dunkler oder heller erscheinen.


/* Design token system with oklch Custom Properties */
:root {
  /* Brand color axes as separate tokens */
  --brand-l: 0.55;
  --brand-c: 0.22;
  --brand-h: 290;

  /* Composed color from axes */
  --color-brand: oklch(var(--brand-l) var(--brand-c) var(--brand-h));
  --color-brand-hover: oklch(calc(var(--brand-l) - 0.1) var(--brand-c) var(--brand-h));
  --color-brand-muted: oklch(var(--brand-l) calc(var(--brand-c) * 0.4) var(--brand-h));
}

/* Dark mode: adjust lightness axis only */
@media (prefers-color-scheme: dark) {
  :root {
    --brand-l: 0.75;  /* lighter in dark mode */
  }
}

/* Palette generation — uniform perceptual steps */
:root {
  --violet-1: oklch(0.97 0.03 290);
  --violet-2: oklch(0.92 0.06 290);
  --violet-3: oklch(0.83 0.10 290);
  --violet-4: oklch(0.72 0.16 290);
  --violet-5: oklch(0.60 0.22 290);
  --violet-6: oklch(0.47 0.22 290);
  --violet-7: oklch(0.36 0.18 290);
  --violet-8: oklch(0.25 0.13 290);
  --violet-9: oklch(0.15 0.07 290);
}

/* oklch gradient with explicit interpolation space */
.hero-bg {
  background: linear-gradient(
    in oklch 135deg,
    oklch(0.25 0.20 290),
    oklch(0.65 0.30 200)
  );
}

7. color-gamut Media Query: P3-Fallbacks richtig einsetzen

Die @media (color-gamut: p3) Media Query ermöglicht es, P3-Farben gezielt nur auf Displays anzuwenden, die den P3-Gamut unterstützen. Das ist die empfohlene Methode, um P3-Farben einzusetzen, ohne dass sRGB-Displays abrupte Farbclipping-Artefakte sehen. Der Grundansatz: Basis-Styles mit sRGB-kompatiblen CSS oklch() Farben definieren, dann innerhalb der color-gamut: p3 Media Query die gesättigteren P3-Varianten überschreiben. Das ist präziser als die @supports-Methode, da ein Browser CSS oklch() unterstützen kann, ohne ein P3-Display zu haben.

In der Praxis ist die Unterscheidung subtiler: Browser clippen P3-Farben auf sRGB-Displays automatisch und möglichst farbtreu. Das Clipping ist in den meisten Fällen gut genug, so dass explizite color-gamut-Fallbacks nur bei Farben nötig sind, bei denen das Clipping den Designintent stark verfälscht – etwa bei sehr gesättigten Grüntönen, die nach Clipping deutlich gräulicher wirken. Für normale Designarbeit mit dem CSS oklch() Farbraum kann man die automatische Browser-Gamut-Kompression nutzen und hat trotzdem ein besseres Ergebnis als mit reinem sRGB.

8. Von hsl() und hex zu oklch() migrieren

Die Migration bestehender CSS-Farbpaletten zum CSS oklch() Farbraum ist keine direkte numerische Umrechnung, sondern eine visuelle Neuinterpretation. Die Konvertierung von hsl(260, 70%, 50%) zu CSS oklch() ergibt andere Zahlenwerte, aber eine wahrnehmungsmäßig ähnliche Farbe. Online-Tools wie die oklch Picker von Björn Ottosson oder das oklch.com-Tool zeigen die CSS oklch()-Entsprechung für jede sRGB-Farbe an. Programmatisch gibt es Konverter-Bibliotheken in JavaScript und Python, die die Umrechnung über den Linear-sRGB-Zwischenraum durchführen.

Der sinnvolle Migrationsweg ist nicht, jede einzelne Farbe zu konvertieren, sondern das System neu zu definieren. Die Brand-Farben werden in CSS oklch() neu kalibriert – mit gleichmäßigen Helligkeitsabständen zwischen den Palettenstufen statt der oft ungleichmäßigen Abstände in legacy hsl()-Paletten. Das Ergebnis ist eine Farbpalette, die sowohl auf sRGB-Displays als auch auf P3-Displays gut aussieht, bessere Kontrastverhältnisse hat und leichter in Custom Properties für Dark Mode und Themes manipulierbar ist. Die einmalige Investition in die Neukalibration der Palette zahlt sich durch bessere visuelle Konsistenz und einfachere Wartung aus.

Eigenschaft hsl() oklch() Vorteil oklch()
Helligkeitsachse Nicht wahrnehmungsgleichmäßig Wahrnehmungsgleichmäßig Konsistente Farbstufen-Abstände
Gamut Nur sRGB sRGB + P3 + Rec2020 Lebhaftere Farben auf P3-Displays
Gradienten-Mittelpunkt Oft grau / entsättigt Gesättigt und lebendig Visuell hochwertigere Verläufe
Dark Mode Anpassung Ungleichmäßige Ergebnisse Vorhersehbar durch L-Achse Einfachere Design-Token-Logik
Browser-Support 2026 Alle Browser, inkl. IE Alle modernen Browser (93%+) Fallback mit @supports sinnvoll

9. oklch() vs. hsl() im direkten Vergleich

Der direkteste Vergleich zwischen CSS oklch() und hsl() zeigt sich bei der Definition einer Farbpalette. Eine sRGB-Palette in hsl() mit gleichmäßig gestuften Helligkeitswerten (10%, 20%, 30%, ..., 90%) erzeugt Farbtöne, die visuell ungleichmäßig wirken – bestimmte Farbwerte erscheinen viel heller oder dunkler als ihr numerischer Helligkeitswert suggeriert. Eine CSS oklch()-Palette mit gleichmäßig gestuften L-Werten (0.1, 0.2, ..., 0.9) erzeugt Farbtöne, die dem Auge tatsächlich als gleichmäßig abgestuft erscheinen, unabhängig vom Farbton.

Das zweite wichtige Unterscheidungsmerkmal ist die Farbsattheit bei Helligkeitsanpassungen. In hsl() bleibt die Sättigung konstant, wenn man die Helligkeit ändert – aber die wahrgenommene Sättigung ändert sich dennoch erheblich, weil Helligkeit und Sättigung in hsl() nicht unabhängig von der menschlichen Wahrnehmung sind. Im CSS oklch() Farbraum ist die Chroma-Achse (C) tatsächlich unabhängig von der Lightness-Achse. Eine Farbe mit konstantem C und variierendem L ändert ihre wahrgenommene Leuchtkraft, ohne die wahrgenommene Reinheit der Farbe zu verändern – was vorhersehbare, sauberere Farbsysteme ermöglicht.

Mironsoft

Design-Tokens, CSS-Farbsysteme und Frontend-Architektur

Farbsystem mit oklch() und Design Tokens aufbauen?

Wir entwickeln moderne CSS-Farbsysteme auf Basis von oklch(), Custom Properties und @layer — wahrnehmungsgleichmäßige Paletten, P3-Unterstützung und automatischer Dark Mode ohne manuelle Farbwert-Kalibration.

Farbsystem-Audit

Analyse bestehender hsl()/hex-Paletten auf Konsistenz und Kontrastkriteria

oklch()-Palette

Neuaufbau des Farbsystems mit oklch() und wahrnehmungsgleichmäßigen Stufen

Dark Mode

Automatischer Dark Mode über oklch()-Lightness-Achse in Custom Properties

10. Zusammenfassung

Der CSS oklch() Farbraum ist 2026 in allen modernen Browsern vollständig unterstützt und bietet drei fundamentale Vorteile gegenüber hsl() und rgb(): eine wahrnehmungsgleichmäßige Helligkeitsachse für konsistente Farbpaletten, Zugang zum P3-Gamut für lebhaftere Farben auf modernen Displays und bessere Farbverlauf-Interpolation ohne entsättigte Mittelpunkte. Die Kombination mit CSS Custom Properties erlaubt elegante Design-Token-Systeme, bei denen einzelne Achsen (Lightness, Chroma, Hue) separat manipuliert werden können – perfekt für Dark-Mode-Implementierungen.

Die Migration von hsl() und Hex-Farben zum CSS oklch() Farbraum ist eine Investition, die sich durch bessere visuelle Konsistenz, einfachere Wartung und zukunftssichere Farbpaletten auszahlt. Explizite P3-Fallbacks sind mit der color-gamut Media Query möglich, aber das automatische Browser-Gamut-Clipping ist für die meisten Anwendungsfälle ausreichend. @supports (background: oklch(0 0 0)) liefert bei Bedarf einen präzisen Fallback für Browser ohne CSS oklch()-Support.

CSS oklch() Farbraum — Das Wichtigste auf einen Blick

L C H Achsen

L = Lightness (0–1), C = Chroma (0–0.4+), H = Hue (0–360). Lightness ist wahrnehmungsgleichmäßig kalibriert.

P3-Gamut

Chroma über 0.37 verlässt sRGB. Browser clippt automatisch auf Display-Gamut. color-gamut: p3 für explizite Kontrolle.

Design Tokens

L, C, H als separate Custom Properties. Dann oklch(var(--l) var(--c) var(--h)). Dark Mode via --l-Anpassung in @media.

Browser-Support 2026

Chrome 111+, Firefox 113+, Safari 15.4+. @supports (background: oklch(0 0 0)) für Fallback. Global 93%+.

11. FAQ: CSS oklch() Farbraum

1Was ist CSS oklch()?
Farbfunktion aus CSS Color Level 4. L (Lightness, wahrnehmungsgleichmäßig, 0–1), C (Chroma), H (Hue, 0–360). Löst fundamentale Probleme von hsl() und rgb().
2Was bedeutet Wahrnehmungsgleichmäßigkeit?
Gleiche numerische L-Abstände = gleich wahrgenommene Helligkeitsunterschiede. hsl() ist das nicht — oklch() ist es durch Kalibrierung an das menschliche Sehsystem.
3P3-Farben mit oklch() nutzen?
Chroma > 0.37 verlässt sRGB. Browser clippt automatisch auf Display-Gamut. color-gamut: p3 für explizite P3-Varianten und sRGB-Fallback.
4Warum bessere Farbverläufe?
Kein entsättigter Grauton in der Mitte bei komplementären Farben. linear-gradient(in oklch, ...) explizit setzen für oklch-Interpolation.
5Dark Mode mit oklch()?
--brand-l als Custom Property. In @media (prefers-color-scheme: dark) nur --brand-l anpassen. Alle Farben passen sich wahrnehmungsgleichmäßig an.
6Browser-Support 2026?
Chrome 111+, Firefox 113+, Safari 15.4+. Global 93%+. @supports (background: oklch(0 0 0)) für Fallback auf hsl() oder hex.
7oklch() vs. lch() — Unterschied?
oklch() basiert auf Oklab — verbesserte Hue-Achse, gleichmäßigere Farbverläufe. lch() basiert auf CIELAB mit bekannten Hue-Artefakten bei Blautönen. oklch() ist die bessere Wahl.
8hsl() zu oklch() konvertieren?
oklch.com zeigt oklch-Entsprechung für jede CSS-Farbe. Sinnvoller: Palette neu kalibrieren statt nur konvertieren — gleichmäßigere Helligkeitsstufen als Ziel.
9color-gamut Media Query?
@media (color-gamut: p3) trifft P3-Displays. P3-Farben gezielt für P3-Displays, sRGB-Fallback für sRGB-Displays. Präziser als @supports für Display-Fähigkeiten.
10oklch() besser für Accessibility?
Ja — wahrnehmungsgleichmäßige Helligkeit macht Kontrast-Berechnungen präziser. Konsistentere WCAG-Kontrastverhältnisse über alle Farbtöne bei gleichen L-Stufen.