Eine grundlegende Übersicht zum Erstellen eines dynamischen und konfigurierbaren Farbschemas
In diesem Beitrag möchte ich meine Gedanken zu Möglichkeiten zur Verwaltung mehrerer Farbschemata in CSS teilen. Demo ansehen.
Falls Sie Videos bevorzugen, finden Sie hier eine YouTube-Version dieses Beitrags:
Übersicht
Wir erstellen ein barrierefreies Farbsystem mit benutzerdefinierten Eigenschaften und calc()
, um eine Webseite zu erstellen, die sich an die Nutzereinstellungen anpasst und gleichzeitig die Erstellung vereinfacht. Wir beginnen mit einer Basisfarbe der Marke und erstellen daraus ein System von Varianten: zwei Textfarben, vier Oberflächenfarben und einen passenden Schatten.
In diesem Leitfaden werden zuerst alle Farben für jedes Farbschema definiert. Erst am Ende werden sie daran gewöhnt, die Seite zu ändern.
Die Marke
Oft ist bereits eine Markenfarbe festgelegt, die als Hex-Farbe oder RGB-Farbe übermittelt wird. Diese GUI-Herausforderung hat die Grundfarbe #0af
. Zuerst muss der Hexadezimalwert für dieses Farbsystem in hsl konvertiert werden.
* {
--brand: #0af;
--brand: hsl(200 100% 50%);
}
Damit die Markenfarbe um beispielsweise 20 % abgedunkelt oder aufgehellt werden kann, müssen die drei Kanäle des HSL-Farbwerts in eigene benutzerdefinierte Eigenschaften extrahiert werden. So gehts:
* {
--brand-hue: 200;
--brand-saturation: 100%;
--brand-lightness: 50%;
}
CSS kann diese Farbeigenschaften berechnen, z. B. calc(var(--brand-lightness) -
20%)
, um den Helligkeitswert um 20 % zu verringern. Dies ist die Grundlage für die Erstellung eines Farbschemas, da CSS alle Farben in derselben Farbfamilie beibehalten kann, indem die Sättigung und Helligkeit in hsl angepasst wird.
Helles Design
Jede Farbvariante wird mit dem entsprechenden Farbschema gekennzeichnet. In diesem Fall wird jeder Variante -light
angehängt.
Marke
Beginnend mit der Markenfarbe wird sie neu erstellt, indem die benutzerdefinierten Eigenschaften --brand-hue
, --brand-saturation
und --brand-lightness
in die Klammern der Funktion „hsl ()
“ eingeschlossen werden, ohne Berechnungen:
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
}
Schriftfarben
Als Nächstes benötigen Sie Textfarben. Bei einem hellen Design sollte der Text sehr dunkel sein. Beachten Sie, dass die Helligkeit der folgenden Farben niedrig ist, deutlich unter 50 %.
* {
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
}
--text1-light
, da es bei 10 % Helligkeit sehr dunkel ist, behält es die hohe Sättigung von 100 % bei, damit die Markenfarbe immer noch durch das dunkle Dunkelblau hindurchscheint.
--text2-light
ist sie nicht ganz so dunkel wie die erste Farbe, die gut ist als Sekundärfarbe, und sie ist auch viel weniger gesättigt.
Oberflächenfarben
Oberflächenfarben sind die Hintergründe, Ränder und andere dekorative Oberflächen, auf denen Text platziert ist. Bei einem hellen Design sind dies die hellen Farben im Gegensatz zu den dunklen Textfarben. Um helle Farben mit HSL zu erstellen, verwenden wir höhere Prozentwerte im dritten Wir verringern auch die Sättigung, damit die hellen Grautöne nicht zu gefärbt erscheinen.
* {
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
}
Es wurden vier Oberflächenfarben erstellt, da für dekorative Farben in der Regel mehr Varianten erforderlich sind, z. B. für interaktive Elemente wie :focus
oder :hover
oder um das Aussehen von Papierschichten zu erzeugen. In diesen Fällen ist es sinnvoll, beim Hovering von --surface2-light
zu --surface3-light
zu wechseln, damit ein Hovering zu einem höheren Kontrast führt (von 99 % Helligkeit auf 92 % Helligkeit, also dunkler).
Schatten
Schatten in einem Farbschema sind unübertroffen, verleihen dem Effekt aber eine lebensechte Natur und heben ihn von unrealistischen, schwarzen Schatten ab. Dazu wird für die Farbe des Schattens die benutzerdefinierte Property „Farbton“ verwendet. Der Farbton ist leicht gesättigt, aber dennoch sehr dunkel. Im Grunde wird ein sehr dunkler, leicht blauer Schatten erzeugt.
* {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
--surface-shadow-light
ist nicht in eine HSL-Funktion eingebunden. Das liegt daran, dass der Wert --shadow-strength
kombiniert wird, um eine gewisse Deckkraft zu erzielen, und CSS die einzelnen Teile benötigt, um Berechnungen durchzuführen. Weitere Informationen finden Sie im Abschnitt Schatten des Rades.
Helle Farben zusammen
Sie müssen nicht lange suchen, um herauszufinden, wie die Lichtfarben erstellt werden. Sie finden sie alle an einem Ort im CSS.
* {
--brand-light: hsl(var(--brand-hue) var(--brand-saturation) var(--brand-lightness));
--text1-light: hsl(var(--brand-hue) var(--brand-saturation) 10%);
--text2-light: hsl(var(--brand-hue) 30% 30%);
--surface1-light: hsl(var(--brand-hue) 25% 90%);
--surface2-light: hsl(var(--brand-hue) 20% 99%);
--surface3-light: hsl(var(--brand-hue) 20% 92%);
--surface4-light: hsl(var(--brand-hue) 20% 85%);
--surface-shadow-light: var(--brand-hue) 10% calc(var(--brand-lightness) / 5);
--shadow-strength-light: .02;
}
Dunkles Design
Die meisten Marken beginnen nicht mit einem dunklen Design. Es ist eine Variante ihres primären, in der Regel helleren Designs. Nutzer wählen ein dunkles Design hingegen oft für unterschiedliche Kontexte aus, z. B. für die Nacht. Aufgrund dieser Faktoren habe ich bei dunklen Designs zwei Dinge im Hinterkopf:
- Nutzer werden dieses Design in der Regel bei Dunkelheit verwenden. Testen Sie es also bei Dunkelheit.
- Die Farben sollten möglichst gedeckt sein, damit sie auf dem Bildschirm nicht zu grell wirken.
Marke
Beim hellen Design wurden die Werte der drei Marken-HSL-Farbkanäle unverändert verwendet, beim dunklen Design nicht. Die Sättigung wird halbiert und die Helligkeit relativ um 50 % reduziert.
* {
--brand-dark: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 2)
calc(var(--brand-lightness) / 1.5)
);
}
Schriftfarben
Bei einem dunklen Design sollten die Textfarben hell sein. Die folgenden Farben haben hohe Werte für die Helligkeit, wodurch sie näher an Weiß kommen.
* {
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
}
Oberflächenfarben
Bei einem dunklen Design sollten die Oberflächenfarben dunkel sein. Die folgenden Farben haben eine geringe Helligkeit und Sättigung. Die erste Oberfläche ist mit 10 % am dunkelsten.
* {
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
}
Schatten
Im dunklen Design sind Schatten oft kaum zu erkennen. Das ist verständlich, da es schwierig ist, etwas abzudunkeln, das bereits ziemlich dunkel ist. Hier kommt --shadow-strength-dark
ins Spiel, da wir damit die Schatten durch Ändern einer Variablen verdunkeln können.
* {
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
Achten Sie auch darauf, wie stark dieser Schatten gesättigt ist. Können Sie die Farbe sehen, wenn Sie sich die Benutzeroberfläche ansehen? Versuchen Sie, die Sättigung aus den Entwicklertools zu entfernen. Was bevorzugen Sie?
Dunkle Farben insgesamt
* {
--brand-dark: hsl(var(--brand-hue) calc(var(--brand-saturation) / 2) calc(var(--brand-lightness) / 1.5));
--text1-dark: hsl(var(--brand-hue) 15% 85%);
--text2-dark: hsl(var(--brand-hue) 5% 65%);
--surface1-dark: hsl(var(--brand-hue) 10% 10%);
--surface2-dark: hsl(var(--brand-hue) 10% 15%);
--surface3-dark: hsl(var(--brand-hue) 5% 20%);
--surface4-dark: hsl(var(--brand-hue) 5% 25%);
--surface-shadow-dark: var(--brand-hue) 50% 3%;
--shadow-strength-dark: .8;
}
Dunkles Design
Bei diesem Farbschema geht es darum, Helligkeit und Sättigung zu kombinieren. Die Sättigung sollte ausreichen, damit der Farbton noch sichtbar ist, aber auch nur knapp die Kontrastwerte erreichen, da sie ohnehin dunkel und kontrastarm sein soll.
Marke
* {
--brand-dim: hsl(
var(--brand-hue)
calc(var(--brand-saturation) / 1.25)
calc(var(--brand-lightness) / 1.25)
);
}
Schriftfarben
* {
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
}
Oberflächenfarben
* {
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
}
Schatten
* {
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
Alle Farben gleichzeitig dimmen
* {
--brand-dim: hsl(var(--brand-hue) calc(var(--brand-saturation) / 1.25) calc(var(--brand-lightness) / 1.25));
--text1-dim: hsl(var(--brand-hue) 15% 75%);
--text2-dim: hsl(var(--brand-hue) 10% 61%);
--surface1-dim: hsl(var(--brand-hue) 10% 20%);
--surface2-dim: hsl(var(--brand-hue) 10% 25%);
--surface3-dim: hsl(var(--brand-hue) 5% 30%);
--surface4-dim: hsl(var(--brand-hue) 5% 35%);
--surface-shadow-dim: var(--brand-hue) 30% 13%;
--shadow-strength-dim: .2;
}
Barrierefreie Farben
Die niedrigste Helligkeit im Satz mit dunklen Textfarben beträgt 65 % und die höchste Helligkeit in den dunklen Oberflächen 25 %. Das entspricht 40 % der Helligkeit und einem gewissen Spielraum zwischen ihnen. Im hellen Design ist ein Weißraum von 55 % vorhanden. Wenn Sie die Helligkeitsunterschiede zwischen Text- und Oberflächenfarben bei etwa 40–50 % halten, können Sie die Farbkontrastverhältnisse hoch halten. Außerdem haben Sie so einen subtilen Hebel, um Anpassungen vorzunehmen, falls die Bewertungen schlecht sind.
Ich nenne sie „bump bump til ya pass“, also die Interaktion, bei der der Helligkeitswert angestoßen wird, bis ein Tool anzeigt, dass ich übergebe.
Alle in dieser Herausforderung erstellten Themen erreichen gute Kontrastwerte. Das abgedunkelte Farbschema hat den niedrigsten Kontrast, erfüllt aber dennoch die Mindestanforderungen. Um anderen im Team zu helfen, gute Kontrastfarben zu verwenden, ist es eine gute Idee, eine Klassenbezeichnung zu erstellen, die eine Oberflächenfarbe mit einer barrierefreien Textfarbe kombiniert.
.surface1 {
background-color: var(--surface1);
color: var(--text2);
}
.surface2 {
background-color: var(--surface2);
color: var(--text2);
}
.surface3 {
background-color: var(--surface3);
color: var(--text1);
}
.surface4 {
background-color: var(--surface4);
color: var(--text1);
}
Strahlender Schatten
Die Themen verwenden eine Dienstprogrammklasse namens .rad-shadow
. Dieser Schatten wurde mit dem Tool Smooth Shadow generiert, das ich sehr schätze. Ich habe das generierte Snippet mit meinen eigenen Farben und Opacity-Berechnungen angepasst. Der Grund dafür war, einen Schatten zu erstellen, den ich innerhalb jedes Farbschemas anpassen konnte.
Dazu habe ich für jedes Farbschema zwei Variablen erstellt, die angepasst werden können: eine Schattenfarbe und eine Schattenstärke. Mit der Farbe können Sie die Sättigung und Dunkelheit anpassen. Mit der Stärke lässt sich die Schattenintensität bei einem dunklen Farbschema ganz einfach erhöhen. Das Endergebnis sah in etwa so aus.
:root {
--surface-shadow-light: var(--brand-hue) 10% 20%;
--shadow-strength-light: .02;
}
.rad-shadow {
box-shadow:
0 2.8px 2.2px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 6.7px 5.3px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .01)),
0 12.5px 10px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 22.3px 17.9px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .02)),
0 41.8px 33.4px hsl(var(--surface-shadow) / calc(var(--shadow-strength) + .03)),
0 100px 80px hsl(var(--surface-shadow) / var(--shadow-strength))
;
}
Wenn ich mit Schatten in meinem Farbschema noch weiter gehen würde, würde ich auch die Schattenwinkel zu einem Design-Token machen, da die Lichtrichtung zwischen allen Schatten des Designs gleich sein sollte.
Verwendung der Farbschemata
Nachdem Sie die Farben vordefiniert haben, ist es an der Zeit, sie in schemaunabhängige Eigenschaften umzuwandeln. Als CSS-Entwickler in diesem Farbschema-Projekt sollten Sie nur selten auf den Wert eines bestimmten Farbschemas zugreifen müssen. Ich möchte es Ihnen so einfach wie möglich machen, sich an das Thema zu halten.
Dazu sollte das Farbschema ausschließlich über die generischen benutzerdefinierten Properties verwendet werden, die wir gleich definieren. So müssen sich die Nutzer der Designvariablen keine Gedanken mehr darüber machen, welches Farbschema derzeit festgelegt ist. Sie müssen nur die Oberflächen- und Textfarben verwenden. Verwenden Sie anstelle von color: var(--text1-light)
color: var(--text1)
. Alle Anpassungen und Drehungen
werden in der CSS-Datei viel höher vorgenommen.
Im folgenden Codeblock wird eine generische benutzerdefinierte Eigenschaft mit der Farbe des hellen Designs verknüpft. Jetzt wird bei allen Verwendungszwecken von var(--brand)
die helle Markenfarbe verwendet.
Helles Design (automatisch)
:root {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
Die Website verwendet jetzt das helle Design. Das ist ein sehr erfolgreicher Moment! Sehen wir uns noch ein paar weitere Beispiele an, in denen wir unsere vordefinierten Farben in anderen Farbschema-Kontexten verwenden.
Dunkles Design (automatisch)
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
}
Helles Design
[color-scheme="light"] {
color-scheme: light;
--brand: var(--brand-light);
--text1: var(--text1-light);
--text2: var(--text2-light);
--surface1: var(--surface1-light);
--surface2: var(--surface2-light);
--surface3: var(--surface3-light);
--surface4: var(--surface4-light);
--surface-shadow: var(--surface-shadow-light);
--shadow-strength: var(--shadow-strength-light);
}
Dunkles Design
[color-scheme="dark"] {
color-scheme: dark;
--brand: var(--brand-dark);
--text1: var(--text1-dark);
--text2: var(--text2-dark);
--surface1: var(--surface1-dark);
--surface2: var(--surface2-dark);
--surface3: var(--surface3-dark);
--surface4: var(--surface4-dark);
--surface-shadow: var(--surface-shadow-dark);
--shadow-strength: var(--shadow-strength-dark);
}
Dunkles Design
[color-scheme="dim"] {
color-scheme: dark;
--brand: var(--brand-dim);
--text1: var(--text1-dim);
--text2: var(--text2-dim);
--surface1: var(--surface1-dim);
--surface2: var(--surface2-dim);
--surface3: var(--surface3-dim);
--surface4: var(--surface4-dim);
--surface-shadow: var(--surface-shadow-dim);
--shadow-strength: var(--shadow-strength-dim);
}
Autoren können die bereitgestellten generischen Farbschemata nach Bedarf verwenden und müssen sich nie wieder Gedanken über Themen machen.
Fazit
Jetzt, da Sie wissen, wie ich das gemacht habe, wie würden Sie es machen? 🙂
Lassen Sie uns unsere Ansätze diversifizieren und alle Möglichkeiten kennenlernen, wie Sie im Web entwickeln können. Erstelle einen Codepen oder hoste deine eigene Demo, tweete mir einen Link dazu und ich füge sie unten in den Abschnitt „Community-Remixe“ ein.
Quelle
Community-Remixe: @chris-kruining hat einen Farbtonregler, Statusfarben und Kontrastmodi für no-preference
, more
und less
hinzugefügt: Demo.