Farbe/Farbmodelle
Farbe ist ein durch das Auge und Gehirn vermittelter Sinneseindruck, der durch Licht hervorgerufen wird. Um diesen subjektiven Eindruck verständlich wiederzugeben, wurden verschiedene Farbmodelle entwickelt, in denen Farben quantitativ (mit Hilfe von Zahlen) beschrieben sind.
Mit den im letzten Kapitel eingeführten Farbnamen kannst Du ca. 150 verschiedene, vordefinierte Farbtöne darstellen. Computergrafikkarten verwenden aber keine Namen, sondern erzeugen Farben durch unterschiedliche Intensitäten der Grundfarben Rot, Grün und Blau. Wieviele unterschiedliche Intensitäten technisch möglich sind, hängt von der verwendeten Technik ab. Das häufigste Farbmodell verwendet 8 Bits pro Kanal, was 224 ≈ 16,7 Millionen Farben ermöglicht. CSS ermöglicht es Ihnen, eine Farbe direkt durch Angabe dieser Farbintensitäten festzulegen. Dabei ergeben sich jedoch auch Schwierigkeiten, auf die wir noch eingehen werden und zu deren Behebung neue Farbmodelle erfunden wurden. Die CSS Colors Level 4 Spezifikation führt die Möglichkeit ein, Farbangaben direkt mit den Mitteln dieser Farbmodelle machen zu können.[1]
Dieses Tutorial besteht aus einem Anfängerteil, der das immer noch dominierende RGB-Modell erklärt und einem zweiten Teil, der die neuen Farbmodelle CIELAB und OKLAB vorstellt und vergleicht.
Inhaltsverzeichnis
RGB-Modell (Rot/Grün/Blau-Mischung)
Beim RGB-Modell wird eine Farbe durch ihre Anteile an den drei Grundfarben Rot, Grün und Blau definiert. Jede Farbe hat also einen Rotwert, einen Grünwert und einen Blauwert.
Die Intensität der drei Grundfarben wird in CSS durch Zahlen zwischen 0
und 255
(8bit-Farbtiefe) definiert. Der Wert 0
bedeutet: keinen Anteil an der betreffenden Grundfarbe, der Wert 255
bedeutet: maximalen Anteil an der betreffenden Grundfarbe. Ein dunkles Blau hat nach diesem Schema z. B. die Farbwerte 0,0,153
. (0 rot, 0 grün, 153 blau
). Mit diesem Schema können 256×256×256 ≈ 16,7 Millionen unterschiedliche Farben definiert werden.
Die folgende SVG Animation zeigt, wie die drei Grundfarben nach dem Prinzip der additiven Farbmischung weitere Farben ergeben.
rgb()
Die am besten lesbare Darstellung für RGB-Farbangaben verwendet die CSS-Funktion rgb(). Die rgb()-Funktion lässt sich sowohl in CSS als auch in SVG verwenden.
rgb(Rot Grün Blau [/ Alphawert])
Der CSS-Funktion werden innerhalb der Klammern die durch Leerzeichen getrennten Intensitätswerte für Rot
, Grün
und Blau
entweder als ganze Zahlen im Bereich 0 - 255
oder Prozentwerte im Bereich von 0% - 100%
übergeben. Eine Mischung von Zahlen- und Prozentangaben in den Farbkanälen ist nicht zulässig.
Der Alphawert bestimmt die Transparenz der Farbe und wird im Anschluss beschrieben.
Farbe | RGB-Wert | Hinweis |
---|---|---|
rgb(51 117 153)
|
SELF-Blau | |
rgb(87% 67% 13%)
|
SELF-Gelb | |
keine | rgb(20 100% 50)
|
Zahlen- und Prozentwerte dürfen nicht vermischt werden. |
Die oben verwendete Notation richtet sich nach der neuesten Version der Spezifikation CSS Colors Level 4.[2]
Dort wurde die bisherige Notation; mehrere Werte durch Kommas zu trennen, zugunsten einer Leerzeichen-separierten Schreibweise, wie sie auch bei anderen CSS-Eigenschaften wie z. B. border, border-radius und box-shadow und CSS-Funktionen wie drop-shadow() verwendet wird, vereinheitlicht.
Auch die neuen, weiter unten beschriebenen, Funktionen lab() und color() verwenden die neue Schreibweise.
Trotzdem wird die alte Schreibweise weiterhin gültig bleiben.
Transparenz mit Alphakanal
Optional kann zur RGB-Mischung noch ein vierter Wert für den Transparenzwert oder die Deckkraft der Farbe hinzugefügt werden. In Grafikprogrammen (und in der CSS Spezifikation) nennt man diese Deckkraft auch den Alphakanal. Der Alphawert wird durch einen Schrägstrich /
von den Farbwerten getrennt und kann als Fließkommazahl 0.0 - 1.0
angegeben werden, optional auch als Prozentwert von 0% bis 100% (was aber intern gleich auf 0 - 1 umgerechnet wird). Der Wert 0 bedeutet vollkommene Transparenz, d.h. die eingestellte Farbe kommt nicht zur Wirkung, und 1 volle Deckkraft. Wenn ein HTML- oder SVG-Element eine Farbe mit Alphawert enthält, so werden für die Darstellung die Rot-, Grün- und Blauwerte eines solchen Bildpunkts mit denen des Hintergrund-Bildpunkts im Verhältnis alpha
zu 1-alpha
gemischt. Ein Alphawert von 0.5 würde also je Bildpunkt den Mittelwert von Rot,- Grün- und Blauintensität in Vorder- und Hintergrundbildpunkt bilden.
Wie man sehen kann, bedeutet eine Transparenz eine blassere, aber nicht automatisch eine hellere Farbe. Dies gilt nur bei einem weißen Hintergrund - im Dark Mode wirken die Farben blasser und dunkler.
Ursprünglich wurde die Angabe des Alphawerts durch eine eigene CSS-Funktion
rgba()
notiert, die den Alphawert einfach als viertes Argument erwartete. Die alte rgb()-Syntax mit Kommas und die rbga()-Funktion wurden zur neuen rbg()-Syntax mit Leerstellen und Schrägstrich verschmolzen.Die rgba()-Funktion wird aber weiterhin gültig bleiben.
Hexadezimale Schreibweise
Die hexadezimale Schreibweise ist auf Grund ihrer Kompaktheit die am weitesten verbreitete Methode, einen RGB-Farbwert anzugeben. Nach einem Gatterzeichen #
(hash) werden die Farbanteile der Farben rot, grün und blau in einem Bereich von 00
(0) bis FF
(255) als Hexadezimalzahl notiert.
Allgemein: #RRGGBB
.
Farbe | Hexadezimaler Wert | Hinweis |
---|---|---|
#337599
|
SELF-Blau aus der SELFHTML-Farbtabelle | |
#dfac20
|
SELF-Gelb | |
#c82f04
|
Rot | |
#93b946
|
helles Grün |
Für den Fall, dass alle Farbwerte einer Farbangabe hexadezimale „Schnapszahlen“ sind (11, 99, EE), erlaubt CSS eine Kurzschreibweise in der Form #RGB. Für die interne Farbfestlegung verdoppelt CSS diese Ziffern wieder.
Farbe | Hexadezimaler Wert | Hinweis |
---|---|---|
#000
|
entspricht #000000 alle Farbwerte sind auf "0" → schwarz | |
#00f
|
entspricht #0000ff kein rot, kein grün, nur blau | |
#0ff
|
entspricht #00ffff kein rot, grün und blau gemischt → cyan | |
#0f0
|
entspricht #00ff00 kein rot, volles grün, kein blau → lime |
Optional kann eine #RRGGBB-Angabe durch zwei weitere Hexadezimalziffern ergänzt werden, die die Deckkraft des Alphakanals angeben. Zwei Hexadezimalziffern ergeben einen Wert von 0 bis 255, der tatsächliche Alphawert ergibt sich deshalb durch Division des hexadezimalen Wertes durch 255. 00
steht also für Alpha=0.0 oder transparent, FF
steht für Alpha=1.0 oder volle Deckkraft. Zwischenwerte beschreiben eine Teiltransparenz (80
entspräche 50%).[3]
Farbe | Hexadezimaler Wert | Hinweis |
---|---|---|
#ff7f5000
|
Entspricht der benannten Farbe „coral“, komplett durchsichtig | |
#ff7f5044
|
Entspricht der benannten Farbe „coral“, teilweise deckend | |
#ff7f5080
|
Entspricht der benannten Farbe „coral“, teilweise deckend | |
#ff7f50cc
|
Entspricht der benannten Farbe „coral“, teilweise deckend | |
#ff7f50ff
|
Entspricht der benannten Farbe „coral“, komplett deckend |
CSS erlaubt auch hier eine Kurzschreibweise. Sie ist dann möglich, wenn die erste und die zweite Ziffer aller Farbwerte und der Deckkraft identisch sind (#RGBA
entspricht #RRGGBBAA
).
Farbton/Sättigung/Helligkeits-Mischung
Da die Mischung von Rot, Grün und Blau oftmals nicht intuitiv stattfindet, erlaubt CSS auch das Mischen von Farbton (englisch hue), Sättigung (englisch saturation) und Helligkeit. Hier haben sich mehrere Varianten herausgebildet, die nun alle unterstützt werden:
hsl()
Eine HSL-Mischung kann mit einer hsl()-CSS-Funktion notiert werden:
hsl(Farbton Sättigung Helligkeit [/ Alphawert])
Sie enthält 3, bzw. 4 durch Leerzeichen getrennte Werte:
- H (hue) (Farbton) ist ein ganzzahliger Wert zwischen
0
und360
. Bei diesem Wertebereich stellt man sich vor, dass die Regenbogenbogenfarben in einem Kreis angeordnet sind.0
entspricht Rot,120
entspricht grün,240
entspricht blau und360
entspricht wieder Rot.
Es sind auch höhere und negative Werte erlaubt, diese Werte werden dann in eine Zahl innerhalb des genannten Bereiches umgewandelt. - S (saturation) (Sättigung): Sie kann man sich als Verlauf des Farbtons (
100%
) zu einem Grauton (0%
) vorstellen.
Sie wird in Prozent ausgedrückt. - L (lightness) (Helligkeit) dagegen verläuft von der Farbe weiß (
100%
) zur Farbe schwarz (0%
). Eine Helligkeit von50%
gilt als normale Helligkeit.
Sie wird in Prozent ausgedrückt.
Optional kann zur HSL-Mischung noch eine Transparenz hinzugefügt werden.
- Die Deckkraft wird als Fließkommazahl im Bereich
0
(keine Deckkraft, vollkommen transparent) bis1
(volle Deckkraft, keine Transparenz) angegeben. Er wird, abweichend von den anderen Werten, mit einem Slash / getrennt.
Farbe | HSL-Wert | Hinweis |
---|---|---|
hsl(13 96% 40%)
|
rot | |
hsl(44 75% 50%)
|
gelb | |
hsl(201 50% 40%)
|
SELF-Blau | |
hsla(201 50% 40% /0.8)
|
80% Deckkraft | |
hsla(201 50% 40% /0.5)
|
50% Deckkraft | |
hsla(201 50% 40% /0.2)
|
20% Deckkraft |
Sättigung | ||||||
---|---|---|---|---|---|---|
100% | 75% | 50% | 25% | 0% | ||
Helligkeit | 100% | |||||
75% | ||||||
50% | ||||||
25% | ||||||
0% |
Ursprünglich wurde die Angabe des Alphawerts durch eine eigene CSS-Funktion
hsla()
mit identischer Syntax und Verhalten notiert. Dies ist heute nicht mehr nötig.Die hsla()-Funktion wird aber weiterhin gültig bleiben.
Helligkeit in HSL
Sowohl die rgb()
-Funktion und die entsprechenden HEX-Werte sind für Menschen nicht intuitiv. Die hsl()
-Funktion scheint da besser geeignet, da Farbton und Helligkeit scheinbar einheitlich wahrgenommen werden.
hsl()
eine Helligkeit von 50%!Ändere die Darstellung im Seiteninpektor auf Graustufen mit Klick auf Barrierefreiheit > Simulieren: Achromatopsie (Keine Farben) oder mit
style="filter: grayscale(1);"
.Was ändert sich?
hsl(30 100% 50%)
hsl(50 100% 50%)
hsl(230 100% 50%)
hsl(250 100% 50%)
Die Farbtönbe sind nur scheinbar hgleichhell, die perceived lightness - die wahrgenommene Helligkeit weicht stark von den hsl-Werten ab.
Aus diesem Grund empfehlen wir, Farben künftig mit der oklch()-Funktion zu notieren.
HSV, HSB bzw hwb()
In der Welt der grafischen Bildbearbeitung gibt es bei Programmen wie Photoshop und Gimp einen etwas anderen Ansatz. Hier wird die oben vorgestellte hue-Farbscheibe mit einem Parameter B für brightness (Helligkeit), bzw. V (value) für den Farbwert kombiniert.
Um es nicht zu einfach zu machen, wurde dies als hwb()-Funktion in CSS implementiert.
hwb(hue whiteness blackness [/ Alphawert])
Sie enthält 3, bzw. 4 durch Leerzeichen getrennte Werte:
- H (hue) (Farbton)
- W (whiteness) (Tönung)
- B (blackness) (Schattierung)
Optional kann zur HWB-Mischung noch eine Transparenz hinzugefügt werden. Sie wird, abweichend von den anderen Werten, mit einem Slash / getrennt.
Anders als in der rgb()-Funktion werden die verschiedenen Farbschattierungen durch Mischung mit Schwarz- und Weißanteilen erreicht.
Im Folgenden geben wir einen Überblick über die anderen neuen Farbfestlegungen:
CIELAB Farbmodelle
Was bis jetzt besprochen wurde, ist besser als die 216 „websicheren Farben“, aber nur ein Bruchteil des für Menschen sichtbaren Spektrums. Das RGB-Modell stammt aus einer Zeit, in der Computer Farbpaletten mit 16, 256 und dann 16,7 Mio Farben darstellen konnten. Die festgelegten Punkte für RGB entsprechen dabei den Grenzen des RGB-Farbraums, wogegen das menschliche Auge noch weitere, außerhalb dieses Farbraums (engl. Gamut) liegende Farben sehen kann. Auch Computer- und Smartphone-Monitore sind heute viel leistungsfähiger als ihre Vorgängermodelle.
Deshalb wurde der sRGB-Raum durch neue Farbräume ergänzt, die mehr Farben darstellen können und diese auch besser aussehen lassen:
Dieses Chromatizitätsdiagramm (CIE1931) zeigt das wahre Erfassungsvermögen (Gamut) des menschlichen Auges innerhalb der „Schuhsohle“. Die Dreiecke repräsentiert die verschiedenen Modelle des RGB-Farbraums - außerhalb liegende Werte können mit RGB nicht dargestellt werden.
(Im Folgenden werden die Begriffe RBG und sRGB - der von Adobe festgelegte Bereich - synonym verwendet.)
Für diese beiden Funktionen verweisen wir auf die entsprechenden Artikel in der CSS-Referenz.
OKLAB-Farbmodell
L*a*b ist eine verständlichere Darstellung des CIE Normfarbraumes, basierend auf L (Helligkeit) und einer Positionierung auf den Komplementärfarbskalen grün/rot sowie blau/gelb. Der L*a*b Farbraum soll besser der menschlichen Wahrnehmung entsprechen, macht aber Schwierigkeiten bei der Bildverarbeitung, weshalb von Björn Ottoson eine verbesserte Umrechnung von XYZ in Lab vorgeschlagen wurde, die beim W3C Anklang fand. Dieses bessere Lab ist "okay", deshalb nannte man es OKLAB.[4]
oklab()
Eine Farbe wird in Oklab mit drei Koordinaten dargestellt, ähnlich wie in CIELAB, aber mit besseren Wahrnehmungseigenschaften. Oklab verwendet einen D65-Weißpunkt, da dieser von sRGB und anderen gängigen Farbräumen verwendet wird. Die drei Koordinaten sind:
- L - wahrgenommene Helligkeit
- a - wie grün/rot die Farbe ist
- b - wie blau/gelb die Farbe ist
Das Arbeiten mit den Parametern a und b war für mich völlig ungewohnt und wenig intuitiv - ein Grund, warum es auch in Fach-Artikeln nur der Vollständigkeit halber erwähnt wird.
Wichtiger ist die verwandte oklch()-Notation im OKLAB-Farbraum:
oklch()
Die oklch()-Funktion scheint vergleichbar mit der hsl()- und der lch()-Funktion, unterscheidet sich aber einerseits durch den Begriff Chroma und durch die unterschiedlichen Wertebereiche.
- L (Lightness): Helligkeit der Farbe, Zahlenangabe von 0-1, als Prozentangabe von 0 % bis 100 % oder Schlüsselwort
none
- C (Chroma): Reinheit der Farbe als Zahlenangabe von 0-0.4, als Prozentangabe von 0 % bis 100 % oder Schlüsselwort
none
; Theoretisch können auch höhere Werte verwendet werden - mehr als 0.5 ist aber nicht darstellbar. - H (Hue): Farbkreis (fast) wie in HSL von 0 bis 360 Grad (siehe unten)
oklch( [ lightness = <percentage (0%-100%)> ] [ chroma <number> (0-0.37) ] [ hue <degrees> (0deg-360deg) ] )
Vergleich und Abgrenzung zu hsl() und lch()
Scheinbar hat sich gegenüber der hsl()-Funktion nicht viel geändert. Allerdings steckt der Teufel im Detail:
- Genau wie in hsl() ist der erste Parameter die Lightness. Während die Helligkeit in hsl() - wie oben beschrieben - nicht mit der perceived lightness - der wahrgenommenen Helligkeit übereinstimmt, stimmt in oklab() die wahrgenommene Helligkeit mit dem angegebenen Wert überein.
- Die Chroma wird in oklch() als Prozentwert oder als Zahlenangabe von 0 - 0.4 angegeben. Damit unterscheidet sie sich von den in lch() verwendeten Werten - die ja übrigens auch in unterschiedlichen Farbräumen „spielen“.
- Während der Farbton (Hue) wie in hsl() durch den Farbkreis wandert, ist der Farbraum größer, weswegen die einzelnen Prozentwerte andere Farbtöne beschreiben!
Dazu ist er etwas verschoben, Rot hat in hsl() einen Hue-Wert von 0° - in oklch() von ca. 30°:
0° | 60° | 120° | 180° | 240° | 300° | |
---|---|---|---|---|---|---|
sRGB | ||||||
CIELAB | ||||||
Oklch |
RGB-Farbraum
oklch() Hue-Farbkreis
Auch bei der Chroma ist - anders als die Sättigung bei hsl() ein (größerer) Farbbereich mit Werten von 0 - 0.37 festgelegt, um nicht nur auf den größeren Wertebereich zuzugreifen, sondern auch wahrnehmbar konsistente Ergebnisse zu erzielen, selbst wenn sich die Werte ändern.
"Chroma bezieht sich auf die Reinheit einer Farbe. Einem Farbton mit hohem Chroma wird kein Schwarz, Weiß oder Grau zugesetzt. Umgekehrt wird durch Hinzufügen von Weiß, Schwarz oder Grau das Chroma reduziert. Es ist ähnlich wie die Sättigung, aber nicht ganz dasselbe. Chroma kann man sich als die Helligkeit einer Farbe im Vergleich zu Weiß vorstellen."
Cameron Chapman: Color Theory For Designers, Part 2: Understanding Concepts And Color Terminology[5]
Der Vergleich der linearen Farbverläufe in rgb(), hsl() und oklch() zeigt sehr gut, dass im oklch()-Model Farbe, Helligkeit und Sättigung (fast) unabhängig von einander eingestellt werden können. Stelle dazu links und rechts gleiche Helligkeit und Sättigung ein, und verändern nur die Farbe. Im oklch()-Verlauf laufen die Farben sauber ineinander. [6]
Dieses Beispiel funktioniert nur in neueren Browsern (FF121+, …); in älteren Browsern wird der Verlauf als hsl() mit den grauen Zone dargestellt.
Fazit
Es scheint einen Konsens zu geben, dass oklch() gegenüber den anderen Farbangaben aufgrund der gleichbleibenden Helligkeit und dem größeren Farbspektrum Vorteile hat.
Langfristig kannst Du mit der relativen Farbsyntax Farbtöne festlegen und diese dann flexibel je nach Einsatzzweck aufhellen oder abdunkeln, ohne neue Farbangaben und Farbpaletten festlegen zu müssen.[7]
Achtung!
Farben außerhalb des RGB-Farbraums werden in einigen hochwertigen Geräten wie iPhones ab 2017 angezeigt, sonst im kleineren RGB-Farbraum dargestellt. --Matthias Scharwies (Diskussion) 13:11, 11. Jan. 2024 (CET)
Besonders attraktiv ist der Color-picker oklch.com der Evil Martians.
Two Things That are Not Great About OKLCH vom 25.05.2023 von Chris Coyier
weitere Modelle
color()
Mit der color()-Funktion können explizit weitere Farbräume, so der P3-Farbraum für Monitore mit großem Farbumfang, definiert werden.[8] Der Farbraum ist ca. 50% größer als der RGB-Farbraum.
Mittlerweile unterstützen alle modernen Browser (Stand: Dezember 2023: >90%) die color()-Funktion. Für ältere Browser könnte man rgb()-Werte als Fallback setzen.
header {
color: rgb(0, 255, 0);
color: color(display-p3 0 1 0);
}
Ältere Browser parsen den ersten Wert und ignorieren den P3-Wert als für sie ungültig.
Bei custom properties solltest Du die @supports-Regel verwenden:
* sRGB color. */
:root {
--bright-green: rgb(0, 255, 0);
}
/* Display-P3 color, when supported. */
@supports (color: color(display-p3 1 1 1)) {
:root {
--bright-green: color(display-p3 0 1 0);
}
}
header {
color: var(--bright-green);
}
Eine weitere Möglichkeit ist das Setzen von Farbwerten innerhalb einer @media-Abfrage:
.warnung {
color: hsl(26.06 99% 51%);
}
@media (color-gamut: p3) {
.warnung {
color: oklch(70.9% 0.195 47.025);
}
}
Hardware Support
- iPhone 7 und neuer
- MacBook und iMac (seit 2015)
- LG UltraFine 5K Display
- Google Pixel 2 XL
- HTC U11+
- OnePlus 6
CMYK-Modell
Das CMYK-Farbmodell ist ein subtraktives Farbmodell, das die technische Grundlage für den modernen Vierfarbdruck bildet. Die Abkürzung CMYK steht für die drei Farbbestandteile Cyan, Magenta, Gelb (Yellow) und den Schwarzanteil Key als Farbtiefe.
Du musst Dir aber keine Sorgen machen, Drucker rechnen die RGB-Farbwerte intern in CMYK um. Außerdem verwenden die meisten Drucker nicht nur die drei oben genannten Farben, sondern für dunkle Flächen als vierte Farbe auch noch schwarz!
Weblinks
- ↑ W3C: CSS Colors Level 4
Mittlerweile wird das CSS Color Module im Level 6 weiterentwickelt: CSS Colors Level 4 - ↑ css-tricks: No-Comma Color Functions in CSS vom 04.12.2020
- ↑ css-tricks: 8-Digit Hex Codes? vom 08.09.2016
- ↑ Falling For Oklch: A Love Story Of Color Spaces, Gamuts, And CSS von Geoff Graham, 23.08.2023 (smashing magazine)
- ↑ Cameron Chapman:Color Theory For Designers, Part 2: Understanding Concepts And Color Terminology
- ↑ Falling For Oklch: A Love Story Of Color Spaces, Gamuts, And CSS von Geoff Graham, 28.08.2023 (smashing magazine)
- ↑ OKLCH in CSS: why we moved from RGB and HSL October 25, 2022 (evilmartians)
- ↑ Wide Gamut Color in CSS with Display-P3 (webkit.org)