Die Eigenschaft color-scheme wird zwar häufiger im Stammverzeichnis festgelegt, kann aber auch für einzelne Elemente festgelegt werden, um sie in ein anderes Farbschema als den Rest der Seite zu zwingen.
Das kann für Komponenten nützlich sein, die immer in einem bestimmten Farbschema angezeigt werden müssen (z.B. immer im dunklen oder hellen Modus).
Beispiel-Anwendungsfälle umfassen Folgendes:
- Elemente, die aus ästhetischen Gründen oft auch auf Seiten im hellen Modus im dunklen Modus angezeigt werden, z.B. Codeblöcke, Mediaplayer, Fotogalerien
- Bereiche, die Medien für einen hellen Hintergrund enthalten (z.B. Bilder, Videos, Illustrationen, Druckvorschauen), können auf den hellen Modus eingestellt werden, auch wenn der Rest der Seite im dunklen Modus ist.
- Elemente, deren Farbschema über eine Einstellung auf Nutzerebene gesteuert wird, z. B. Komponentenvorschauen
- Eingebettete Inhalte, die nicht sowohl den hellen als auch den dunklen Modus unterstützen
- Designtools, Karten, Visualisierungen, Spiele usw.
Wann sollten Farben geändert werden und wann sollte color-scheme erzwungen werden?
Nicht jedes Element, das im hellen Modus hellen Text auf dunklem Hintergrund oder im dunklen Modus dunklen Text auf hellem Hintergrund verwendet, benötigt einen anderen color-scheme.
Beispielsweise kann eine primäre Schaltfläche im hellen Modus blau mit weißem Text dargestellt werden, aber das rechtfertigt kein color-scheme: dark.
Als Faustregel gilt: Elemente mit einem anderen color-scheme-Wert sind in der Regel komplexe Oberflächen, die einen eigenen visuellen Kontext herstellen, und keine einfachen, flachen Container.
Wenn Sie erwägen, ein anderes color-scheme für ein Element zu verwenden, stellen Sie sich die folgenden Fragen:
- Sollte die integrierte Browser-UI, die nicht anderweitig angepasst ist (z. B. Formularsteuerelemente, Scrollleisten usw.), dieses Farbschema verwenden oder sich an das Farbschema der Seite anpassen? -> Wenn Letzteres der Fall ist, verwende nicht
color-scheme. - Sollen alle
light-dark()-Farben wie auf dem Rest der Seite oder basierend auf der Überschreibung aufgelöst werden? -> Wenn Letzteres der Fall ist, verwende nichtcolor-scheme. - Sollten Nachkommen in diesem
color-schemesein? Andernfalls sollten Siecolor-schemenicht verwenden.
Einfache Implementierung
Komponentenspezifische Überschreibungen werden in der Regel (wenn auch nicht unbedingt) auf Seiten verwendet, die auch mehrere Farbschemas über ein globales color-scheme unterstützen.
Informationen zur optimalen Implementierung des dunklen Modus für die gesamte Seite findest du unter Dunkler Modus.
Sobald ein seitenweites color-scheme vorhanden ist und Sie Farb-Tokens verwenden, die darauf reagieren (z.B. über light-dark()), können Sie color-scheme einfach für bestimmte Komponenten festlegen, um den Farbmodus für diesen Unterbaum zu überschreiben:
pre, code, .dark {
color-scheme: dark;
}
Beachten Sie, dass einige Browser Komponenten ohnehin automatisch an ein anderes Farbschema anpassen.
Wenn Sie das angegebene Farbschema in allen Fällen erzwingen möchten, verwenden Sie only, also color-scheme: only dark; anstelle von color-scheme: dark;.
Nicht-Farbwerte anpassen
light-dark() funktioniert derzeit nur für Farben.
Best Practices
- OBLIGATORISCH: Legen Sie
color-schemenicht für Elemente ohne Hintergrund fest, da sonst die Gefahr besteht, dass Hintergrund- und Textfarbpaare aus verschiedenen Farbschemas gemischt werden, was zu unlesbarem Text führt. - OPTIONAL: Es ist zwar einfacher, dieselben Farbpaare wie für den seitenweiten dunklen Modus zu verwenden, wir können aber auch andere Farbpaare für diese Komponenten definieren. Beispielsweise möchten wir, dass eine Komponente im dunklen Modus, die auf einer Seite im hellen Modus verwendet wird, etwas weniger dunkel ist als dieselbe Komponente im dunklen Modus, die auf einer Seite verwendet wird, die insgesamt im dunklen Modus ist.
Bekannte Probleme
Wichtiger Hinweis: Vererbung von light-dark()-Farben
light-dark() wird zum Zeitpunkt der Berechnung des Werts aufgelöst.
Das bedeutet, dass alle übernommenen <color>-Eigenschaften, die auf eine light-dark()-Farbe festgelegt sind, nur eine der beiden Farben an ihre untergeordneten Elemente weitergeben, nicht den light-dark()-Ausdruck selbst.
Dazu zählen:
- Integrierte Farbeigenschaften, die übernommen werden, z. B.
color,accent-color,fill,stroke,text-shadow,caret-color - Alle registrierten vererbbaren benutzerdefinierten Eigenschaften mit
syntax: <color>undinherits: true - Alle anderen
<color>-Attribute, die aufinheritfestgelegt sind
Beachten Sie Folgendes:
- Registrieren Sie benutzerdefinierte Eigenschaften, die Design-Tokens enthalten sollen (z.B.
--surface-color), NICHT als<color>. Tokens müssen ihrenlight-dark()Express Online beibehalten, damit Nachfolgerelemente sie unter einem anderencolor-schemeneu auflösen können. - Wenn Sie
color-schemefür ein Element festlegen, müssen Sie alle übernommenen<color>-Eigenschaften, die möglicherweise auflight-dark()-Werte festgelegt wurden (direkt oder über Design-Tokens), noch einmal angeben, auch wenn es sich um dasselbe Design-Token handelt. inheritNICHT für<color>-Properties von Elementen mit einercolor-scheme-Überschreibung verwenden (kann für deren untergeordnete Elemente verwendet werden).- DO use registered
<color>properties for the opposite use case: when you deliberately want to snapshot the ancestor's resolved color and prevent it from re-resolving under the descendant'scolor-scheme. Beispielsweise, um den Seitenhintergrund zu erfassen und an anderer Stelle zu verwenden. - Wenn Sie eine Farbe animieren müssen, verwenden Sie eine separate, mit
@propertyregistrierte<color>-Property für das zu animierende Element. Die Registrierung ist für die Farbinterpolation erforderlich. Dies ist kein Design-Token, sondern ein Animationstarget pro Element, sodass es nicht mit der obigen Regel in Konflikt steht.
Beispiel:
:root {
--accent-color: light-dark(blue, skyblue);
--surface-color: light-dark(white, #222);
--text-color: light-dark(#111, white);
color-scheme: light dark;
accent-color: var(--accent-color);
color: var(--text-color);
}
body {
/* --surface-color dynamically switches despite being inherited because --surface-color is not registered */
background: var(--surface-color);
}
pre, code {
color-scheme: dark;
background: var(--surface-color);
/* Without this, accent-color would be blue, not skyblue! */
accent-color: var(--accent-color);
/* Without this, text-color would be #111, not white! */
color: var(--text-color);
}
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);
}