CSS-Syntax für relative Farben

Erstellen Sie neue Farben basierend auf den Kanälen und Werten einer anderen Farbe.

Adam Argyle
Adam Argyle

In Chrome 119 ist eine sehr leistungsfähige Farbfunktion aus CSS-Farbstufe 5 verfügbar. Die relative Farbsyntax schafft einen weichen Pfad für die Farbbearbeitung in CSS und bietet Autoren und Designern folgende Möglichkeiten:

Um die Deckkraft einer Farbe zu ändern, müssen Sie vor der relativen Farbsyntax benutzerdefinierte Eigenschaften für die Kanäle einer Farbe (in der Regel HSL) erstellen und sie zu einer endgültigen Farbe und der endgültigen Variantenfarbe kombinieren. Das bedeutet, viele Farbstücke zu verwalten, was schnell mühsam werden kann.

:root {
  --brand-hue: 300deg;
  --brand-saturation: 75%;
  --brand-lightness: 50%;

  --brand-hsl:
    var(--brand-hue)
    var(--brand-saturation)
    var(--brand-lightness);

  --brand-color: hsl(var(--brand-hsl));

  /* all this work just so I can set the opacity to 50% in a variant */
  --brand-color-variant: hsl(var(--brand-hsl) / 50%);
}

Nach der relativen Farbsyntax können Sie eine Markenfarbe mit einem beliebigen Farbraum oder jeder erforderlichen Syntax und eine Variante mit halber Deckkraft mit viel weniger Code erstellen. Außerdem ist es viel einfacher, die Absicht der Stile und des Systems zu lesen.

:root {
  --brand-color: hsl(300deg 75% 50%);
  --brand-color-variant: hsl(from var(--brand-color) h s l / 50%);
}

In diesem Beitrag erfährst du mehr über die Syntax und häufig verwendete Farben.

Wenn Sie ein Video bevorzugen, wird fast der gesamte folgende Artikel in dieser GUI Challenge behandelt.

Syntaxübersicht

Das Ziel der relativen Farbsyntax besteht darin, eine Farbe aus einer anderen Farbe abzuleiten. Die Grundfarbe wird als ursprüngliche Farbe bezeichnet. Das ist die Farbe, die nach dem neuen from-Keyword folgt. Der Browser konvertiert diese ursprüngliche Farbe, hebt sie auf und bietet die Teile als Variablen zur Verwendung in der neuen Farbdefinition an.

Es wird ein Diagramm der Syntax rgb(aus grün r g b / alpha) angezeigt, mit einem Pfeil, der den oberen Rand von grün ausgeht und sich zum RGB-Anfang der Funktion wölbt. Dieser Pfeil wird in 4 Pfeile unterteilt, die dann auf die entsprechende Variable zeigen. Die 4 Pfeile sind rot, grün, blau und Alpha. Rot und Blau haben den Wert 0, Grün
128 und Alpha 100%.

Das obige Diagramm zeigt, wie die ursprüngliche Farbe green in den Farbraum der neuen Farbe konvertiert und in einzelne Zahlen umgewandelt wird, die als die Variablen r, g, b und alpha dargestellt werden und dann direkt als Werte einer neuen rgb()-Farbe verwendet werden.

Dieses Bild zeigt zwar die Aufschlüsselung, den Prozess und die Variablen, aber es ändert sich auch nicht die Farbe. Die Variablen werden unverändert in die Farbe zurückgesetzt, sodass weiterhin eine grüne Farbe angezeigt wird.

Das Keyword from

Der erste Teil der Syntax, der lernen soll, ist der Teil from <color>, zusätzlich zur Angabe einer Farbe. Sie wird kurz bevor Sie die Werte angeben. Hier sehen Sie ein Codebeispiel, bei dem nur from green direkt vor der Angabe der Werte für rgb() hinzugefügt wurde.

.syntax-introduction_same-colors {
  color: green;
  color: rgb(0 128 0);
  color: rgb(from green r g b);    /* result = rgb(0 128 0) */
}

Wenn dieses from-Keyword als erster Parameter in funktionaler Notation gesehen wird, ändert sich die Farbdefinition in eine relative Farbe. Nach dem Keyword from erwartet das CSS eine Farbe, die zur nächsten Farbe inspirieren soll.

Farbkonvertierung

Einfacher ausgedrückt wird Grün in die Kanäle r g und b zur Verwendung in einer neuen Farbe konvertiert.

rgb(from green r g b)           /* r=0 g=128 b=0 */
rgb(from rgb(0 128 0) r g b);   /* r=0 g=128 b=0 */

Farben aus benutzerdefinierten Eigenschaften

Lesen von rgb from green ist sehr verständlich und leicht verständlich. Aus diesem Grund passen benutzerdefinierte Eigenschaften und die relative Farbsyntax so gut zueinander, da Sie das Geheimnis der Farbe from entlarven können. Außerdem müssen Sie das Farbformat der benutzerdefinierten Eigenschaft „Farbe“ in der Regel nicht kennen, da Sie eine neue Farbe in einem Format Ihrer Wahl erstellen.

rgb(from rgb(255 105 180) r g b) /* ????? */
rgb(from var(--hotpink) r g b)   /* clear */

In Ihrem bevorzugten Farbraum arbeiten

Sie können den Farbraum mit der von Ihnen gewünschten funktionalen Farbnotation auswählen.

rgb(from hsl(120 100% 25%) r g b)     /*  r=0   g=128  b=0    */
hsl(from hsl(120 100% 25%) h s l)     /*  h=120 s=100% l=25%  */
hwb(from hsl(120 100% 25%) h w b)     /*  h=120 w=0%   b=50%  */
lch(from hsl(120 100% 25%) l c h)     /*  l=46  c=68   h=134  */

Die relative Farbsyntax enthält diesen Konvertierungsschritt. Die Farbe nach from wird in den Farbraum umgewandelt, wie am Anfang der relativen Farbe angegeben. Die Eingabe und die Ausgabe müssen nicht übereinstimmen, was sehr aufregend ist.

Die Möglichkeit, einen Farbraum auszuwählen, trägt auch zur Stärkung bei, da die Auswahl eines Farbraums tendenziell stärker auf die Art der Farbwechsel fokussiert ist als eine Präferenz. Die Präferenz liegt in den Ergebnissen, nicht auf dem Farbformat oder den Kanaltypen. In den Abschnitten zu Anwendungsfällen wird dies deutlicher, da unterschiedliche Farbräume für verschiedene Aufgaben besonders gut geeignet sind.

Variablen vermischen, anpassen, weglassen und wiederholen

Bei dieser Syntax ist es seltsam, aber auch interessant. Die Variablen müssen nicht wieder in die richtige Reihenfolge gebracht werden und können wiederholt werden.

rgb(from green g g g)    /* rgb(128 128 128) */
rgb(from green b r g)    /* rgb(0 0 128) */
rgb(from green 0 0 g)    /* rgb(0 0 128) */

Deckkraft als Variable

Die Syntax liefert auch die Deckkraft als Variable mit dem Namen alpha. Er ist optional und folgt in der funktionalen Farbnotation auf /.

rgb(from #00800080 r g b / alpha)             /* alpha=50% */
rgb(from rgba(0,128,0,.5) r g b / alpha)      /* alpha=50% */
rgb(from rgb(0 128 0 / 50%) r g b / alpha)    /* alpha=50% */

„calc()“ oder andere CSS-Funktionen für die Variablen verwenden

Bisher haben wir immer wieder die Farbe Grün geschaffen. Sie erlernen die Syntax und machen sich mit den Konvertierungs- und der destruktiven Schritten vertraut. Jetzt ist es an der Zeit, die Variablen zu ändern und die Ausgabe so zu ändern, dass sie nicht mit der Eingabe identisch ist.

green                              /*  h=120 s=100% l=25%  */
hsl(from green calc(h * 2) s l)    /*  h=240 s=100% l=25%  */

Jetzt ist es dunkelblau! Der Farbton wurde verdoppelt und den Farbton 120 in 240 umgewandelt, wodurch die Farbe komplett verändert wurde. Damit bewegte sich der Farbton entlang des Farbrads, ein praktischer Trick, der mit zylindrischen Farbräumen wie HSL, HWB, LCH und OKLCH ganz einfach gestaltet wurde.

Mit diesem Tool für Kanalwerte für relative Farbsyntax können Sie die Werte von Channels visuell darstellen, sodass Sie die Berechnungen vornehmen können, ohne zu raten oder sich die Spezifikation merken zu müssen. Es zeigt jeden Channel-Wert basierend auf der von Ihnen angegebenen Syntax an, sodass Sie genau wissen, welche Werte Ihnen zum Spielen zur Verfügung stehen.

Browserunterstützung prüfen

@supports (color: rgb(from white r g b)) {
  /* safe to use relative color syntax */
}

Anwendungsfälle und Demonstrationen

Die folgenden Beispiele und Anwendungsfälle haben viele alternative Syntaxen, um ähnliche oder gleiche Ergebnisse zu erzielen. Die Variationen ergeben sich aus den Farbräumen und den verfügbaren Kanälen.

Außerdem enthalten viele Beispiele Farbanpassungen mit der Formulierung by und to. Eine by mit einer geänderten Farbe ist eine relative Farbänderung. Dabei wird der Wert der Variablen verwendet und basierend auf ihrem aktuellen Wert eine Anpassung vorgenommen. Eine to mit einer Farbänderung ist eine absolute Farbänderung. Dabei wird der Wert der Variable nicht verwendet, sondern ein komplett neuer Wert angegeben.

Alle Demos finden Sie in dieser Codepen-Sammlung.

Eine Farbe aufhellen

Die besten Ergebnisse beim Aufhellen von Farben liefern die Farbräume OKLCH, OKLAB, XYZ oder sRGB.

Um einen Wert aufhellen

Im folgenden Beispiel .lighten-by-25 wandelt die Farbe blue in OKLCH um. Dann wird das Blau aufgehellt. Dazu wird der Kanal l (Helligkeit) durch Multiplizieren des aktuellen Werts mit 1.25 erhöht. Dadurch wird die blaue Helligkeit um 25 % in Richtung Weiß gedrängt.

.lighten-by-25 {
  background: oklch(from blue calc(l * 1.25) c h);
}

Auf einen bestimmten Wert aufhellen

Im folgenden Beispiel von .lighten-to-75 wird der Kanal l nicht zum Aufleuchten von blue verwendet. Stattdessen wird der Wert vollständig durch 75% ersetzt.

.lighten-to-75 {
  background: oklch(from blue 75% c h);
}

Eine Farbe abdunkeln

Dieselben Farbräume, die zum Aufhellen einer Farbe effektiv sind, eignen sich auch zum Abdunkeln von Farben.

Ein wenig dunkler

Im folgenden Beispiel wird mit .darken-by-25 die Farbe Blau in OKLCH umgewandelt. Dann dunkelt es das Blau ab. Dazu wird der Kanal l (Helligkeit) um 25% verringert, indem der Wert mit .75 multipliziert wird. Dadurch wird die blaue Farbe um 25 % in Richtung Schwarz geschoben.

.darken-by-25 {
  background: oklch(from blue calc(l * .75) c h);
}

Auf einen bestimmten Wert abdunkeln

Im folgenden Beispiel für .darken-to-25 wird der Kanal l nicht zum Abdunkeln von blue verwendet. Stattdessen wird der Wert vollständig durch 25% ersetzt.

.darken-to-25 {
  background: oklch(from blue 25% c h);
}

Eine Farbe sättigen

Um einen bestimmten Wert gesättigt

Im folgenden .saturate-by-50-Beispiel wird der s von hsl() verwendet, um die Vibration von orchid um einen relativen 50% zu erhöhen.

.saturate-by-50 {
  background: hsl(from orchid h calc(s * 1.5) l);
}

Bis zu einem bestimmten Betrag sättigen

Im folgenden Beispiel für .saturate-to-100 wird der s-Kanal von hsl() nicht verwendet. Stattdessen wird ein gewünschter Sättigungswert angegeben. In diesem Beispiel wird die Sättigung auf 100% erhöht.

.saturate-to-100 {
  background: hsl(from orchid h 100% l);
}

Farbe entsättigen

Um einen bestimmten Wert entsättigen

Im folgenden Beispiel von .desaturate-by-half wird die s von hsl() verwendet, um die Sättigung von indigo um die Hälfte zu reduzieren.

.desaturate-by-half {
  background: hsl(from indigo h calc(s / 2) l);
}

Auf einen bestimmten Wert entsättigen

Anstatt um einen bestimmten Wert zu entsättigen, können Sie sie auf einen bestimmten gewünschten Wert entsättigen. Im folgenden Beispiel wird mit .desaturate-to-25 eine neue Farbe basierend auf indigo erstellt, aber die Sättigung wird auf 25 % festgelegt.

.desaturate-to-25 {
  background: hsl(from indigo h 25% l);
}

Chroma verstärken eine Farbe

Dieser Effekt ähnelt der Sättigung einer Farbe, unterscheidet sich jedoch in einigen Punkten. Erstens ist es eine chroma- und keine saturation-Änderung. Das liegt daran, dass die Farbräume, die für einen hohen dynamischen Bereich optimiert werden können, keine Sättigung verwenden. Die Farbräume mit chroma sind High Dynamic Range-fähig, wodurch Autoren die Farbintensität weiter steigern können, als es mit der Sättigung überhaupt möglich wäre.

.increase-chroma {
  background: oklch(from orange l calc(c + .1) h);
}

Deckkraft einer Farbe anpassen

Das Anfertigen einer halbtransparenten Variante einer Farbe ist eine der häufigsten Farbanpassungen in Designsystemen. Falls Sie es übersehen haben, sehen Sie sich das Beispiel in der Einführung dieses Artikels an. Es beschreibt den Problembereich sehr gut.

Deckkraft um einen bestimmten Wert anpassen

.decrease-opacity-by-25 {
  background: rgb(from lime r g b / calc(alpha / 2));
}

Deckkraft auf einen bestimmten Wert anpassen

.decrease-opacity-to-25 {
  background: rgb(from lime r g b / 25%);
}

Farbe invertieren

Die Farbumkehr ist eine gängige Farbanpassungsfunktion in Farbbibliotheken. Eine Möglichkeit, dies zu erreichen, besteht darin, eine Farbe in RGB zu konvertieren und dann den Wert jedes Kanals von 1 zu subtrahieren.

.invert-each-rgb-channel {
  background: rgb(from yellow calc(255 - r) calc(255 - g) calc(255 - b));
}

Eine Farbe ergänzen

Wenn Ihr Ziel nicht war, eine Farbe umzukehren, sondern sie zu ergänzen, ist die Farbtonrotation wahrscheinlich das, wonach Sie suchen. Wählen Sie einen Farbraum aus, in dem der Farbton als Winkel angeboten wird, und drehen Sie den Farbton mit calc() um den gewünschten Wert. Das Komplement einer Farbe wird ermittelt, indem um eine halbe Umdrehung gedreht wird. In diesem Fall können Sie den h-Kanal mit 180 addieren oder subtrahieren, um das Ergebnis zu erzielen.

.complementary-color {
  background: hsl(from blue calc(h + 180) s l);
}

Farbe kontrastieren

Als Methode zum Erreichen barrierefreier Farbkontrastverhältnisse sollten Sie L&midast; (Lstar) in Betracht ziehen. Dabei wird der (annähernd) wahrnehmungsgleiche Helligkeitskanal (L) aus LCH und OKLCH in einem calc() verwendet. Je nachdem, ob Sie ein Targeting auf einen niedrigen, mittleren oder hohen Kontrast vornehmen, liegt das L&midast;-Delta bei etwa 40, 50 oder 60.

Diese Technik funktioniert gut für jeden Farbton in LCH oder OKLCH.

Eine dunklere Farbe kontrastieren

Die Klasse .well-contrasting-darker-color zeigt L* mit einem Delta von 60. Da es sich um eine dunkle Farbe (geringfügige Helligkeit) handelt, werden dem Helligkeitskanal 60% (0,6) hinzugefügt. Mit dieser Technik wird eine kontrastreiche, dunkle Textfarbe mit gleichem Farbton auf hellem Hintergrund gefunden.

.well-contrasting-darker-color {
  background: darkred;
  color: oklch(from darkred calc(l + .60) c h);
}

Eine hellere Farbe kontrastieren

Die Klasse .well-contrasting-lighter-color zeigt L* mit einem Delta von 60 % ebenfalls. Da es sich bei der Ausgangsfarbe um eine helle Farbe (hohe Helligkeit) handelt, wird 0,60 vom Helligkeitskanal subtrahiert.

.well-contrasting-lighter-color {
  background: lightpink;
  color: oklch(from lightpink calc(l - .60) c h);
}

Farbpaletten

Die relative Farbsyntax ist sehr gut zum Erstellen von Farbpaletten. Aufgrund der vielen verfügbaren Farbräume ist dies besonders nützlich und leistungsstark. In den folgenden Beispielen wird OKLCH verwendet, da der Helligkeitskanal zuverlässig ist und der Farbtonkanal ohne Nebeneffekte gedreht werden kann. Das letzte Beispiel zeigt eine Kombination aus Anpassungen von Helligkeit und Farbtonrotation, um ein interessanteres Ergebnis zu erzielen.

Öffnen Sie den Beispielcode für diese Paletten und ändern Sie --base-color, um zu sehen, wie dynamisch diese Paletten sind. Es macht Spaß!

Wenn dir das Video gefällt, gebe ich detaillierte Informationen zum Erstellen von Farbpaletten in CSS mit OKLCH auf YouTube.

Einfarbige Paletten

Um eine monochromatische Palette zu erstellen, erstellen Sie eine Palette alle aus demselben Farbton, aber mit Variationen von Helligkeit und Dunkelheit. Die mittlere Farbe ist die Quellfarbe für die Palette, wobei auf jeder Seite zwei hellere und zwei dunklere Varianten platziert werden.

:root {
  --base-color: deeppink;

  --color-0: oklch(from var(--base-color) calc(l + .20) c h); /* lightest */
  --color-1: oklch(from var(--base-color) calc(l + .10) c h);
  --color-2: var(--base-color);
  --color-3: oklch(from var(--base-color) calc(l - .10) c h);
  --color-4: oklch(from var(--base-color) calc(l - .20) c h); /* darkest */
}
Probieren Sie verschiedene Paletten aus, die mit der relativen Farbsyntax und OKLCH erstellt wurden.

Open Props, eine Bibliothek mit kostenlosen CSS-Variablen, bietet Farbpaletten, die mit dieser Strategie erstellt wurden, und erleichtert die Verwendung mit einem Import. Sie basieren auch alle auf einer Farbe, die Sie anpassen können. Sie geben ihr einfach eine Farbe und es wird eine Palette erstellt.

Analoge Paletten

Da die Farbtonrotation mit OKLCH und HSL so einfach ist, ist es einfach, eine analoge Farbpalette zu erstellen. Drehen Sie den Farbton um einen Betrag, der Ihnen gefällt, und ändern Sie die Grundfarbe. Beobachten Sie, wie neue Paletten vom Browser erstellt werden.

:root {
  --base-color: blue;

  --primary:   var(--base-color);
  --secondary: oklch(from var(--base-color) l c calc(h - 45));
  --tertiary:  oklch(from var(--base-color) l c calc(h + 45));
}

Triadische Paletten

Ähnlich wie Komplementärfarben sind es bei triadischen Farbpaletten gegensätzliche, aber harmonische Farbrotationen, bei denen eine Grundfarbe verwendet wird. Wenn sich eine Komplementärfarbe auf der gegenüberliegenden Seite einer Farbe befindet, z. B. eine gerade Linie, die durch die Mitte des Farbrads gezeichnet wird, sind triadische Paletten wie ein Dreieck aus Linien und es werden zwei Farben gefunden, die gleichmäßig von einer Grundfarbe rotiert sind. Dazu rotieren Sie den Farbton 120deg.

Dies ist eine kleine Vereinfachung der Farbtheorie, aber es reicht aus, um die komplexeren triadischen Farbpaletten kennenzulernen.

:root {
  --base-color: yellow;
  --triad-1: oklch(from var(--base-color) l c calc(h - 120));
  --triad-2: oklch(from var(--base-color) l c calc(h + 120));
}

Tetradische Paletten

Tetradische Paletten bestehen aus vier Farben, die gleichmäßig über das Farbrad verteilt sind. Dies ergibt eine Palette ohne klar dominanten Wert. Sie könnten sich das auch als zwei Paar Komplementärfarben vorstellen. Mit Bedacht eingesetzt kann dies sehr aussagekräftig sein.

Dies ist eine leichte Vereinfachung der Farbtheorie, aber es reicht aus, um die komplexeren tetradischen Farbpaletten kennenzulernen.

:root {
  --base-color: lime;

  --color-1: var(--base-color);
  --color-2: oklch(from var(--base-color) l c calc(h + 90));
  --color-3: oklch(from var(--base-color) l c calc(h + 180));
  --color-4: oklch(from var(--base-color) l c calc(h + 270));
}

Einfarbig mit leichter Farbrotation

Viele Farbexperten halten diesen Trick auf dem Ärmel. Das Problem ist, dass eine einfarbige Farbskala ziemlich langweilig sein kann. Die Lösung besteht darin, jeder neuen Farbe entweder eine Neben- oder Hauptfarbrotation hinzuzufügen, wenn sich die Helligkeit ändert.

Im folgenden Beispiel wird die Helligkeit jedes Musters um 10% verringert und der Farbton um 10 Grad gedreht. Das Ergebnis ist eine Palette von Heißrosa zu Indigo, die sich nahtlos wie ein Farbverlauf verschmelzen lässt.

:root {
  --base-color: deeppink;

  --color-1: var(--base-color);
  --color-2: oklch(from var(--base-color) calc(l - .10) c calc(h - 10));
  --color-3: oklch(from var(--base-color) calc(l - .20) c calc(h - 20));
  --color-4: oklch(from var(--base-color) calc(l - .30) c calc(h - 30));
  --color-5: oklch(from var(--base-color) calc(l - .40) c calc(h - 40));
}
Testen Sie dieses Leaderboard, das mit OKLCH und Farbton-Rotation erstellt wurde

In der folgenden Bestenlisten-Oberfläche wird diese Farbton-Rotationsstrategie verwendet. Jedes Listenelement verfolgt seinen Index im Dokument als Variable --i. Anhand dieses Index werden dann Chroma, Helligkeit und Farbton angepasst. Die Anpassung erfolgt nur um 5% oder 5°, also wesentlich subtiler als das obige Beispiel mit Deeppink. Daher sollte man genau hinsehen, um zu erkennen, warum diese Bestenliste einen beliebigen Farbton dieser Eleganz haben kann.

Ändern Sie unbedingt den Farbton im Schieberegler unter dem Leaderboard, um zu sehen, wie die relative Farbsyntax für schöne Farbmomente sorgt.

li {
  --_bg: oklch(
    /* decrease lightness as list grows */
    calc(75% - (var(--i) * 5%))

    /* decrease chroma as list grows */
    calc(.2 - (var(--i) * .01))

    /* lightly rotate the hue as the list grows */
    calc(var(--hue) - (var(--i) + 5))
  );
}