BlogCSS Snippet

color-mix(): eine Variable statt neun Hex-Codes

Eine Markenfarbe genügt: color-mix() leitet Hover, Aktiv-Zustand, Hintergrund und Rahmen direkt in der CSS ab, ohne dass jede Variante von Hand gepflegt werden muss.

von Oli Feiler · 4. Juli 2026

Eine Markenfarbe wird in der Praxis selten allein gebraucht. Ein Button braucht einen Hover-Zustand, eine Fläche einen dezenten Hintergrund, eine Kante einen zurückhaltenden Rahmen. Wer das klassisch löst, legt für jede Variante einen eigenen Hex-Wert an und pflegt am Ende sieben, acht, neun Farben von Hand, die bei jeder Anpassung der Markenfarbe manuell nachgezogen werden müssen. In der Praxis laufen diese Werte fast immer auseinander.

Die CSS-Funktion color-mix() löst das im Browser. Sie berechnet Zwischenfarben zur Laufzeit aus einer einzigen Quelle und ist seit Mai 2023 in allen gängigen Browsern verfügbar (Chrome 111+, Firefox 113+, Safari 16.2+, Edge 111+). Tailwind nutzt sie seit Version 4 bereits intern für ihre Opacity-Modifier.

Die Syntax nimmt zwei Farben und einen Farbraum

            .element {
  background: color-mix(in oklch, #7c5cff 80%, black);
}
        

in oklch legt den Farbraum fest, in dem gemischt wird. Danach folgen die beiden Farben mit ihrem jeweiligen Anteil. Wird nur ein Prozentwert angegeben, ergibt sich der zweite automatisch als Rest zu 100 Prozent. Damit lässt sich das eingangs beschriebene Set direkt aus einer Variable ableiten, für jeden Anwendungsfall einzeln:

Für einen Hover-Zustand, der die Markenfarbe dezent abdunkelt:

            --hover: color-mix(in oklch, var(--brand), black 12%);
        

Für einen gedrückten oder aktiven Zustand mit stärkerem Kontrast:

            --active: color-mix(in oklch, var(--brand), black 22%);
        

Für eine dezente Fläche im Hintergrund:

            --surface: color-mix(in oklch, var(--brand), white 90%);
        

Für einen zurückhaltenden Rahmen:

            --border: color-mix(in oklch, var(--brand), white 64%);
        

Der Farbraum entscheidet, wie natürlich das Ergebnis wirkt

color-mix() akzeptiert eine Reihe von Farbräumen, in der Praxis relevant sind vor allem drei. oklch mischt wahrnehmungsgleich: Der Übergang von Marke zu Schwarz oder Weiß verläuft in gleichmäßigen Schritten, ohne die stumpfen Zwischentöne, die bei klassischer RGB-Interpolation entstehen. Für abgeleitete Paletten aus einer Quelle ist das fast immer die richtige Wahl.

Der Name geht auf den schwedischen Ingenieur Björn Ottosson zurück, der Ende 2020 in einem privaten Blogbeitrag ein neues Farbmodell vorstellte. Ottosson kam aus der Spieleentwicklung (unter anderem FIFA und Battlefield bei EA DICE) und war mit den gängigen Farbräumen für einfache Aufgaben wie das Abdunkeln einer Farbe unzufrieden. Sein Modell nannte er Oklab, in bewusster Bescheidenheit: nicht perfekt, aber für den Zweck brauchbar, eben "ok". Oklch ist die polare Variante davon, Farbton als Winkel statt als Koordinate, im selben Verhältnis, in dem Lch die polare Variante von Lab ist. Über Chris Lilley beim W3C fand die Arbeit ihren Weg in die CSS-Color-4-Spezifikation, seit 2023 unterstützen alle gängigen Browser sie.

srgb mischt dagegen so, wie es die meisten aus Sass oder Less gewohnt sind, direkter und etwas kräftiger. Bei bereits stark gesättigten Markenfarben (kräftiges Rot, Neongrün) kann das sogar die bessere Wahl sein: oklch muss solche Farben beim Mischen intern in den darstellbaren Farbraum zurückrechnen, das sogenannte Gamut-Mapping. Das Ergebnis wirkt dann blasser als im Code angegeben, ohne dass eine Fehlermeldung darauf hinweist.

hsl funktioniert ebenfalls, mischt aber entlang von Helligkeit statt Wahrnehmung. Die Zwischenschritte sind seltener gleichmäßig, dafür bleibt die Syntax vertraut für alle, die von HSL-basierten Systemen kommen.

Dieselbe Farbraum-Wahl gilt nicht nur für color-mix(), sondern auch für Verläufe. Dazu mehr im Snippet zu linear-gradient() in oklch.

Ein Muster, das sich auf das ganze System skalieren lässt

Ändert sich --brand, aktualisieren sich Hover, Aktiv-Zustand, Fläche und Rahmen automatisch mit. Für White-Label-Varianten oder ein zweites Theme reicht eine einzige geänderte Zeile.

            :root {
  --brand: #7c5cff;
  --hover: color-mix(in oklch, var(--brand), black 12%);
  --active: color-mix(in oklch, var(--brand), black 22%);
  --surface: color-mix(in oklch, var(--brand), white 90%);
  --border: color-mix(in oklch, var(--brand), white 64%);
}
        
--brand
hover
active
surface
border

Prozentwerte, die sich nicht zu 100 Prozent summieren, verändern die Transparenz

Ein Detail wird selten erwähnt und sorgt entsprechend häufig für Überraschungen: Summieren sich die beiden Prozentwerte nicht zu 100 Prozent, normalisiert die Spezifikation sie zwar proportional, verrechnet die fehlende Differenz aber zusätzlich als Alphawert.

            /* 30 % + 30 % = 60 % */
color-mix(in oklch, red 30%, blue 30%);
/* Wirkung: Farbe wird im Verhältnis 50/50 gemischt,
   das Ergebnis erhält zusätzlich 60 % Deckkraft */
        

Wer ein vollständig deckendes Ergebnis will, sollte die Prozentwerte auf 100 Prozent summieren oder ganz weglassen. Der Effekt lässt sich aber auch gezielt nutzen, etwa um aus einer Volltonfarbe eine transparente Variante zu erzeugen:

            --brand-75: color-mix(in srgb, var(--brand) 75%, transparent);
        

Was einer aus --brand abgeleiteten Fläche noch fehlt, ist eine dazu passende Textfarbe. Auch die lässt sich berechnen statt hart zu codieren:

            .card {
  --bg: color-mix(in oklch, var(--brand), white 90%);
  background: var(--bg);
  color: contrast-color(var(--bg));
}
        

Wie contrast-color() diese Entscheidung im Detail trifft und wo ihre Grenzen liegen, ist Thema des nächsten Snippets.

Zusammenfassung

FarbraumEigenschaftEmpfehlung
oklch / oklabWahrnehmungsgleiche AbstufungenStandardwahl für abgeleitete Paletten
srgbDirektere, oft kräftigere MischungBei bereits stark gesättigten Markenfarben
hslVertraute Syntax, ungleichmäßige HelligkeitsschritteNur bei einfachen Anwendungen

Glossar

color-mix()

CSS-Funktion, die zwei Farben in einem festgelegten Verhältnis und Farbraum zur Laufzeit im Browser mischt.

oklch

Perzeptuell gleichmäßiger Farbraum, 2020 von Björn Ottosson entwickelt. Gleiche numerische Schritte wirken für das menschliche Auge gleich groß, anders als bei klassischem RGB oder HSL.

Gamut-Mapping

Der Vorgang, mit dem ein Browser eine Farbe, die außerhalb des darstellbaren Farbraums liegt, auf den nächstmöglichen darstellbaren Wert zurückrechnet.

Custom Property

Eine in CSS definierte Variable (--name), die an beliebiger Stelle im Stylesheet wiederverwendet und zur Laufzeit verändert werden kann.

 alt=

Farbsysteme, die mitwachsen.

Wir entwickeln Websites und Plattformen, in denen sich Themes, Zustände und White-Label-Varianten aus wenigen Grundfarben ableiten lassen, robust von Anfang an statt nachträglich zusammengeflickt.
Oli Feiler, UI-Designer