Die Property color-scheme gibt an, welche Farbschemata (z. B. hell oder dunkel) deine Seite unterstützt. Dadurch wird der Browser darüber informiert, dass er native UI-Elemente wie Scrollleisten, Formularsteuerelemente und den Standardhintergrund des Canvas automatisch an das Design Ihrer Website anpassen kann. So werden weiße Blitze beim ersten Laden minimiert.
Implementierung
1. Unterstützte Schemas in HTML deklarieren
OBLIGATORISCH: Um ein „Aufblitzen von Inhalten ohne Design“ (FOUC) zu verhindern, fügen Sie ein <meta>-Tag in Ihr <head> ein. So weiß der Browser, welche Designs Sie unterstützen, bevor er mit dem Rendern beginnt. Dieses <meta>-Tag hilft zwar, FOUC zu vermeiden, indem die anfängliche Canvas-Farbe frühzeitig festgelegt wird, aber es kann sein, dass das Aufblitzen nicht in allen Browsern oder unter allen Ladebedingungen vollständig verhindert wird.
<!-- MANDATORY: Declare support for both light and dark themes -->
<meta name="color-scheme" content="light dark">
2. Seitenweites Farbschema auf CSS :root oder html anwenden
OBLIGATORISCH: Wende die Property color-scheme auf das Element html oder die Pseudoklasse :root an. Browser suchen speziell nach dem Stammelement, um das Design für den gesamten Darstellungsbereich zu bestimmen, einschließlich der Stamm-Scrollleisten und des ursprünglichen „Canvas“-Hintergrunds. Wenn sie nur auf das body angewendet werden, bleiben diese globalen UI-Oberflächen möglicherweise im hellen Modus, da das body den Rendering-Kontext des Fensters nicht steuert.
/* MANDATORY: Apply color-scheme to :root or html for viewport-wide theming */
:root {
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
}
3. Helle und dunkle Farb-Tokens definieren
Mit der Funktion light-dark() können Sie Farb-Tokens definieren, die sich automatisch an verschiedene color-scheme-Werte anpassen.
Es wird empfohlen, die Rohfarbwerte auch in separaten benutzerdefinierten Eigenschaften zu speichern. So lassen sie sich leichter auf verschiedene Arten kombinieren und bei Bedarf ist das Fallback-Verhalten einfacher.
Wenn Sie mehr Kontrolle über die Farben der integrierten Benutzeroberfläche wie accent-color oder scrollbar-color haben möchten, können Sie optional eigene dynamische Farben mit benutzerdefinierten Eigenschaften und/oder der Funktion light-dark() hinzufügen. Diese Funktion wählt automatisch die richtige Farbe basierend auf dem berechneten color-scheme des Elements aus und macht redundante Medienabfragen überflüssig. Sie ist jedoch für eine einfache Implementierung nicht erforderlich.
:root {
--color-brand-light: oklch(45% 0.23 270);
--color-brand-dark: oklch(85% 0.15 210);
--color-brand-text-light: white;
--color-brand-text-dark: oklch(40% 0.23 270);
--color-brand: light-dark(var(--color-brand-light), var(--color-brand-dark));
--color-brand-text: light-dark(var(--color-brand-text-light), var(--color-brand-text-dark));
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
}
button.primary {
/* These automatically adapt to color scheme */
background-color: var(--color-brand);
color: var(--color-brand-text);
}
OPTIONAL: Es sind verschiedene Systemfarben verfügbar, die sich auch automatisch an das verwendete Farbschema (und andere Farbmodi, z. B. erzwungene Farben) anpassen, z. B. canvas, canvastext, accentcolor (Unterstützung prüfen), buttonborder usw. Diese sind in der Regel zu eingeschränkt, um nützlich zu sein, außer in sehr spezifischen Fällen, in denen Sie bestimmte Standard-Browser-UIs genau anpassen müssen, oder als Fallbacks/Standardwerte.
OPTIONAL: Farbkombinationen an den Kontext anpassen
Auch wenn Sie die Standardeinstellung des Systems überschreiben, kann es nützlich sein, die Medienabfrage prefers-color-scheme zu verwenden, um verschiedene Farbpaare zu definieren, die die Farben des Browsers und des Betriebssystems um die Seite herum (oder der umgebenden Seite, wenn die Seite als iFrame verwendet wird) berücksichtigen.
Verwenden Sie beispielsweise ein etwas dunkleres helles Design, wenn die Systemeinstellung dark ist, oder ein kontrastreicheres dunkles Design, wenn die Systemeinstellung light ist, damit die Seite nicht visuell von der umgebenden Benutzeroberfläche überlagert wird.
Detaillierte Anpassung der Browser-Benutzeroberfläche
Wenn Sie color-scheme festlegen, wird die Browser-UI bereits an das verwendete Farbschema angepasst. Dabei werden jedoch die Standardeinstellungen des Betriebssystems und/oder die Systemfarben verwendet, die möglicherweise nicht perfekt zum Websitedesign passen.
Moderne Browser bieten dafür mehrere detaillierte Anpassungsmöglichkeiten.
Implementieren Sie native Steuerelemente nicht neu, nur um ihr Erscheinungsbild anzupassen, ohne die von modernen Browsern bereitgestellten Anpassungs-Hooks auszuschöpfen.
Akzentfarbe festlegen
Einige Elemente der Browser-UI (z.B. aktivierte Kästchen oder Schieberegler) verwenden eine Akzentfarbe.
Standardmäßig wird die Betriebssystemeinstellung verwendet. Mit der Property accent-color können Sie jedoch eine Farbe festlegen, die besser zur Seite passt, z. B. die Markenfarbe der Seite.
html {
accent-color: light-dark(var(--color-accent-light), var(--color-accent-dark));
}
Probleme, die bei der Verwendung von „accent-color“ auftreten können
Das Browser-Rendering von accent-color variiert.
Für Indikatoren, die im Allgemeinen über einen Akzentfarbenhintergrund gezeichnet werden, z. B. Häkchen in Kästchen und Punkte in Optionsfeldern, können Browser unterschiedliche Behandlungen anwenden:
- Chromium und Firefox wählen in der Regel eine kontrastierende Farbe für die Anzeige aus.
- In Safari wird im hellen Modus möglicherweise ein weißer Indikator und im dunklen Modus ein schwarzer Indikator beibehalten, während die Akzentfarbe dahinter geändert wird. Diese Anpassung bietet nicht immer ausreichenden Kontrast für jede angegebene Farbe. Testen Sie daher wichtige Kombinationen in Safari, einschließlich heller und dunkler Farbschemas. Gehen Sie nicht davon aus, dass Safari automatisch die Farbe für die Anzeige auswählt, die den besten Kontrast bietet.
Farben der Bildlaufleiste
Sie können scrollbar-color zusammen mit light-dark() verwenden, um benutzerdefinierte Scrollleistenfarben festzulegen, die sich an das verwendete Farbschema anpassen.
:root {
--color-scrollbar-track: light-dark(#eee, #222);
--color-scrollbar-thumb: light-dark(#999, #666);
scrollbar-color: var(--color-scrollbar-thumb) var(--color-scrollbar-track);
}
Probleme bei der Verwendung von „scrollbar-color“
scrollbar-colordarf NICHT animiert oder mit Übergängen versehen werden. Ein WebKit-Fehler führt dazu, dass die Bildlaufleiste jedes Mal flackert, wenn sichscrollbar-colorändert.- Unter macOS werden die Eigenschaften
scrollbar-color(Standard) und::-webkit-scrollbar(Legacy) standardmäßig ignoriert, da macOS native „Overlay“-Scrollleisten verwendet. Sie MÜSSEN benutzerdefinierte Farben mitscrollbar-width(z.B.thinoderauto) koppeln, damit macOS sie rendert. - Auch wenn
scrollbar-widthangewendet wird, wird die Spur (der Zwischenraum) bei macOS-Overlay-Scrollleisten standardmäßig transparent dargestellt. Wenn das Design unter macOS eine sichtbare Hintergrundfarbe für die Bildlaufleiste erfordert, MÜSSEN Siescrollbar-gutter: stable;auf den scrollbaren Container anwenden. Beachten Sie jedoch, dass die Hintergrundfarbe erst angezeigt wird, wenn der Nutzer den Mauszeiger auf die Bildlaufleiste bewegt. - Selbst mit
scrollbar-gutter: stablekann der Track unter macOS transparent sein. Die Sichtbarkeit des Schiebereglers sollte nicht von der Farbe der Schiene abhängen.
Weitere Anpassungsmöglichkeiten
Die meisten Browser-UIs stellen Pseudoelemente bereit, mit denen sich das Erscheinungsbild vollständig anpassen lässt, z. B.:
::placeholder::spelling-error::grammar-error::selection::search-text::target-text::file-selector-button
Sie können light-dark()-Farben für alle diese Elemente verwenden, um Farben anzuwenden, die sich an das verwendete Farbschema anpassen.
4. Unterschiedliche Bilder für den hellen und den dunklen Modus
Für CSS-Bilder kann light-dark() auch verwendet werden, um verschiedene Bildwerte bereitzustellen.
WICHTIG: Beide Werte in light-dark() müssen vom selben Typ sein. Sie können eine Farbe nicht mit einem Bild kombinieren.
Wenn einer der beiden Werte ein Bild sein muss, verwenden Sie image(<color>), um den Farbwert einzuschließen.
JS-basierte Designerkennung
Die meisten Verzweigungen des Farbschemas sollten in CSS erfolgen, da sich CSS automatisch an Änderungen anpasst.
Jedes JS, das matchMedia("(prefers-color-scheme: dark)").matches liest, MUSS auch das Ereignis change verarbeiten, da sich die Systemeinstellung jederzeit ändern kann.
OPTIONAL: Farbschema-Umschalter implementieren
Wenn du Nutzern erlauben möchtest, die Standardeinstellung des Systems für diese Website manuell zu überschreiben, kannst du einen Schalter für den dunklen Modus implementieren. Die meisten Websites benötigen keine dauerhafte Ein-/Aus-Schaltfläche in der Website-UI. In der Regel reicht es aus, das Standardfarbschema des Systems zu verwenden, optional mit einer Einstellung in einer separaten Einstellungsoberfläche. Unter Umschaltflächen für den dunklen Modus finden Sie Best Practices für die Implementierung einer Umschaltfläche für den dunklen Modus (dauerhaft oder nicht).
OPTIONAL: Komponentenspezifische Überschreibungen
Sie können das globale Design für bestimmte Elemente überschreiben, indem Sie color-scheme für sie festlegen.
Weitere Informationen und Hinweise finden Sie unter Komponentenspezifische helle/dunkle Designs.
Bekannte Probleme
Probleme, die bei der Verwendung von „color-scheme“ auftreten können
- Chrome und Firefox berücksichtigen
color-schemefür iFrames: Sie rendern eingebettete Seiten im richtigen Farbschema und passen die Medienabfrageprefers-color-schemeder eingebetteten Seite an, um dascolor-schemedes Einbettungskontexts widerzuspiegeln. Safari tut dies nicht und löstprefers-color-schemeauch innerhalb von iFrames in die Systemeinstellung auf.- Wenn Sie sowohl die übergeordnete Seite als auch den iFrame steuern: Übergeben Sie das Farbschema der übergeordneten Seite explizit an den iFrame – entweder über einen URL-Parameter (
?theme=dark) beim Erstellen des iFrames oder überpostMessage()(damit können Sie auch auf Änderungen während der Laufzeit reagieren). Legen Sie im iFrame eine Klasse für<html>(und/odercolor-schemefür:root) aus diesem Signal fest, anstatt sich aufprefers-color-schemezu verlassen. - Wenn Sie nur die eingebettete Seite kontrollieren: Es gibt keine zuverlässige Möglichkeit, die
color-schemedes Einbettungskontexts in Safari innerhalb des iFrames zu erkennen. Stellen Sie einen expliziten Designparameter in Ihrer Einbettungs-API bereit (z.B. einen Abfragestring oder einpostMessage-Protokoll) und dokumentieren Sie ihn für Einbettende.
- Wenn Sie sowohl die übergeordnete Seite als auch den iFrame steuern: Übergeben Sie das Farbschema der übergeordneten Seite explizit an den iFrame – entweder über einen URL-Parameter (
Fallback-Strategien
Fallbacks und Browserunterstützung für „color-scheme“
Das Attribut color-scheme ist eine progressive Verbesserung.
Browser, die diese Funktion nicht unterstützen, ignorieren dieses Attribut und verwenden ihre Standard-UI für den hellen Modus.
Wenn Sie die Einstellungen des Nutzers in älteren Browsern berücksichtigen möchten, verwenden Sie prefers-color-scheme-Medienabfragen, um unterschiedliche Farben bereitzustellen, wenn der dunkle Modus bevorzugt wird.
- Verwenden Sie die Medienabfrage, um benutzerdefinierte Eigenschaften für
:rootoderhtmlzu aktivieren. - Vermeiden Sie die Verwendung der Medienabfrage für einzelne Komponenten, es sei denn, die Komponente erfordert eine sehr spezifische Anpassung des dunklen Modus, die über Farben hinausgeht.
:root {
/* Define brand colors for each mode */
--color-brand-light: #0056b3;
--color-brand-dark: #00e5ff;
--color-brand: var(--color-brand-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--color-brand: var(--color-brand-dark);
}
/* Ignored in older browsers */
color-scheme: light dark;
}
button.primary {
background-color: var(--color-brand);
}
Fallbacks und Browserunterstützung für „light-dark()“
Für Browser, die color-scheme, aber noch nicht light-dark() unterstützen, sollten helle und dunkle Versionen von Farben zuerst als benutzerdefinierte Eigenschaften definiert werden. Die Medienabfrage prefers-color-scheme sollte verwendet werden, um Farben für den jeweiligen Modus festzulegen, wie im folgenden Beispiel:
:root {
/* Define browser UI accent color for each mode */
--brand-accent-light: #0056b3;
--brand-accent-dark: #00e5ff;
--accent-color: var(--brand-accent-light);
/* MANDATORY: Fallback for browsers without light-dark support */
@media (prefers-color-scheme: dark) {
--accent-color: var(--brand-accent-dark);
}
/* OPTIONAL: use light-dark() for more control of built-in UI colors */
@supports (color: light-dark(white, black)) {
--accent-color: light-dark(var(--brand-accent-light), var(--brand-accent-dark));
}
/* MANDATORY: Automatically adapt native UI to user system preferences */
color-scheme: light dark;
/* Example inherited color property */
accent-color: var(--accent-color);
}
pre, code {
color-scheme: dark;
/* **Mandatory**: any inherited color properties must be set again, even if to the same design tokens */
accent-color: var(--accent-color);
}
Fallbacks und Browserunterstützung für „light-dark()“-Bildwerte
Verwenden Sie für Browser, die light-dark() für Bilder nicht unterstützen, image-set() als Schalter: Weisen Sie jeder Option einen type() aus einer benutzerdefinierten Eigenschaft zu und legen Sie für die inaktive Option einen nicht unterstützten MIME-Typ fest, damit der Browser diese Option verwirft.
Die aktive Option erhält einen leeren Wert, sodass es sich um eine einfache image-set()-Option ohne type() handelt.
Definieren Sie den Schalter einmal auf :root. An jeder Verwendungsstelle müssen dann nur beide Images inline angegeben werden, z. B. light-dark().
:root {
--light-type: ;
--dark-type: type("image/do-not-use");
/* MANDATORY: Fallback for browsers without light-dark() image support */
@media (prefers-color-scheme: dark) {
--light-type: type("image/do-not-use");
--dark-type: ;
}
}
.hero {
background-image: image-set(url(hero-light.png) var(--light-type), url(hero-dark.png) var(--dark-type));
@supports (background-image: light-dark(url("a"), url("b"))) {
background-image: light-dark(url(hero-light.png), url(hero-dark.png));
}
}
- Es wird nur das ausgewählte Bild heruntergeladen.
- Die folgenden Auflösungen funktionieren weiterhin:
image-set(url(a-1x.png) 1x var(--light-type), url(a-2x.png) 2x var(--light-type), url(b-1x.png) 1x var(--dark-type), url(b-2x.png) 2x var(--dark-type)). - Verwenden Sie NICHT
type("")für die aktive Option. Browser behandeln den leeren String als nicht unterstützt und verwerfen alle Optionen. - Im Gegensatz zu
light-dark()folgt der Switch nicht dercolor-scheme, die für eine Unterstruktur festgelegt wurde. Ein manueller Schalter oder ein Unterbaum, dercolor-schemefestlegt, MUSS auch--light-typeund--dark-typeumschalten.
Alternative: eine benutzerdefinierte Eigenschaft pro Bild
Einfacher, wenn nur wenige Bilder variieren, aber jedes Bild benötigt einen eigenen Medienabfrage-Zweig und muss manuell umgeschaltet werden.
:root {
--hero-image: url(hero-light.png);
@media (prefers-color-scheme: dark) {
--hero-image: url(hero-dark.png);
}
@supports (background-image: light-dark(url("a"), url("b"))) {
--hero-image: light-dark(url(hero-light.png), url(hero-dark.png));
}
}
.hero {
background-image: var(--hero-image);
}
Fallbacks und Browserunterstützung für image()
Verwenden Sie einen Farbverlauf mit einem einzelnen Farbstopp und ohne Positionen, z.B. linear-gradient(blue).
Für eine breitere Browserunterstützung können Sie explizit 0 100%-Positionen für den einzelnen Farbstopp angeben, z.B. linear-gradient(blue 0 100%).
Fallbacks und Browserunterstützung für „scrollbar-color“
Diese Funktion ist eine progressive Verbesserung und erfordert nicht immer Fallbacks.
Wenn das Styling wichtig ist und das Baseline-Ziel des Nutzers „Baseline – allgemein verfügbar“ oder früher ist, SOLLTEN Sie die nicht standardmäßigen ::-webkit-scrollbar-Pseudoelemente als Fallbacks einfügen.
Setzen Sie Legacy-Fallbacks in einen @supports not (scrollbar-color: auto)-Block, um Konflikte zwischen Standard-Properties und Legacy-WebKit-Selektoren in Browsern zu vermeiden, die beide nativ unterstützen.
Wenn Sie benutzerdefinierte Eigenschaften verwenden, um Farben zu definieren, werden diese automatisch auf die alten WebKit-Selektoren übertragen. Sie müssen sie NICHT duplizieren.
/* Legacy fallback for WebKit/Blink browsers */
@supports not (scrollbar-color: auto) {
.scroller::-webkit-scrollbar {
/* Must define base size in WebKit for custom colors to be visual */
width: 12px;
height: 12px;
}
.scroller::-webkit-scrollbar-thumb {
background: var(--scrollbar-thumb);
}
.scroller::-webkit-scrollbar-track {
background: var(--scrollbar-track);
}
}
Fallbacks und Browserunterstützung für „accent-color“
Das Attribut accent-color ist eine progressive Verbesserung.
Browser, die diese Eigenschaft nicht unterstützen, ignorieren sie und verwenden ihre Standard-UI-Farben.