De property color-scheme geeft aan welke kleurenschema's (zoals licht of donker) je pagina ondersteunt. Hiermee laat je de browser weten dat deze automatisch systeemeigen UI-elementen (zoals schuifbalken, formulierbedieningselementen en de standaard canvasachtergrond) kan aanpassen aan het ontwerp van je site en witte flitsen tijdens het laden kan minimaliseren.
Implementatie
1. Ondersteunde schema's declareren in HTML
VERPLICHT: Plaats een <meta>-tag in je <head> om een 'flits van content zonder thema' (FOUC) te voorkomen. Zo weet de browser welke thema's je ondersteunt voordat de weergave begint. Hoewel deze <meta>-tag FOUC helpt te voorkomen door de oorspronkelijke canvaskleur vroeg in te stellen, worden flitsen misschien niet in alle browsers of laadomstandigheden volledig geëlimineerd.
<!-- MANDATORY: Declare support for both light and dark themes -->
<meta name="color-scheme" content="light dark">
2. Kleurenschema voor de hele pagina toepassen op CSS :root of html
VERPLICHT: Pas de eigenschap color-scheme toe op het element html of de pseudoklasse :root. Browsers kijken specifiek naar het hoofdelement om het thema voor de hele viewport te bepalen, inclusief de hoofdscrollbalken en de oorspronkelijke canvasachtergrond. Als deze alleen worden toegepast op de body, blijven deze algemene UI-platforms misschien in de lichte modus omdat de body de weergavecontext van het venster niet beheert.
/* 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. Lichte en donkere kleur-tokens definiëren
Je kunt de functie light-dark() gebruiken om kleurtoken te definiëren die zich automatisch aanpassen aan verschillende color-scheme-waarden.
We raden je aan de onbewerkte kleurwaarden ook in afzonderlijke aangepaste eigenschappen te houden. Zo kun je ze makkelijker op verschillende manieren combineren (en is het makkelijker om terugvalgedrag te gebruiken, indien nodig).
Voor meer controle over de kleuren van de ingebouwde UI, zoals accent-color of scrollbar-color, kunnen auteurs optioneel hun eigen dynamische kleuren toevoegen met aangepaste eigenschappen en/of de functie light-dark(). Deze functie kiest automatisch de juiste kleur op basis van de berekende color-scheme van het element en maakt overbodige mediaquery's overbodig, maar is niet vereist voor een basisimplementatie.
: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);
}
OPTIONEEL: Er zijn een aantal systeemkleuren beschikbaar die zich ook automatisch aanpassen aan het gebruikte kleurenschema (en andere kleurmodi, zoals geforceerde kleuren), zoals canvas, canvastext, accentcolor (check de ondersteuning), buttonborder, enzovoort. Deze zijn meestal te beperkt om nuttig te zijn, behalve in zeer specifieke gevallen waarin je precies bepaalde standaardbrowser-UI's of fallbacks/standaardwaarden nodig hebt.
OPTIONEEL: Kleurparen aanpassen aan de context
Zelfs als je de systeemstandaard overschrijft, kan het nuttig zijn om de mediaquery prefers-color-scheme te gebruiken om verschillende kleurparen te definiëren die rekening houden met de kleuren van de browser en het OS-chroom rond de pagina (of van de omringende pagina, als de pagina wordt gebruikt als iframe).
Gebruik bijvoorbeeld een iets lichter thema als de systeeminstelling dark is of een donker thema met meer contrast als de systeeminstelling light is, zodat de pagina visueel niet wordt overschaduwd door de omringende UI.
Gedetailleerde aanpassing van de browser-UI
De instelling color-scheme past de browser-UI al aan het gebruikte kleurenschema aan, maar hierbij worden OS-standaardinstellingen en/of systeemkleuren gebruikt die misschien niet perfect aansluiten bij het websiteontwerp.
Moderne browsers bieden verschillende gedetailleerde aanpassingshooks hiervoor.
Implementeer systeemeigen bedieningselementen niet opnieuw om hun uiterlijk aan te passen zonder de aanpassingshooks van moderne browsers te gebruiken.
De accentkleur instellen
Sommige UI-elementen van de browser (zoals aangevinkte selectievakjes of schuifregelaars) gebruiken een accentkleur.
Dit wordt standaard omgezet naar de OS-instelling, maar je kunt de property accent-color gebruiken om de kleur in te stellen op een kleur die beter bij de pagina past, zoals de merkkleur van de pagina.
html {
accent-color: light-dark(var(--color-accent-light), var(--color-accent-dark));
}
Problemen om rekening mee te houden bij het gebruik van accent-color
De browserweergave van accent-color varieert.
Voor indicatoren die meestal over een achtergrond met accentkleur worden geschilderd, zoals selectievakjes en keuzerondjes, kunnen browsers verschillende behandelingen toepassen:
- Chromium en Firefox selecteren meestal een contrasterende indicatorkleur.
- Safari kan in plaats daarvan een witte indicator behouden in de lichte modus of een zwarte indicator in de donkere modus, terwijl de accentkleur erachter wordt aangepast. Deze aanpassing biedt niet altijd voldoende contrast voor elke geleverde kleur. Test daarom belangrijke combinaties in Safari, waaronder zowel lichte als donkere kleurenschema's. Ga er niet van uit dat Safari automatisch de indicatorkleur kiest die het beste contrast biedt.
Kleuren van scrollbalk
Je kunt scrollbar-color samen met light-dark() gebruiken om aangepaste scrollbalkkleuren in te stellen die zich aanpassen aan het gebruikte kleurenschema.
: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);
}
Problemen om rekening mee te houden bij het gebruik van scrollbar-color
- Gebruik GEEN animaties of overgangen voor
scrollbar-color. Door een WebKit-bug flikkert de schuifbalk elke keer datscrollbar-colorverandert. - Op macOS worden de eigenschappen
scrollbar-color(standaard) en::-webkit-scrollbar(verouderd) standaard genegeerd, omdat macOS systeemeigen overlay-scrollbalken gebruikt. Je MOET aangepaste kleuren koppelen aanscrollbar-width(bijvoorbeeldthinofauto) om macOS te dwingen ze weer te geven. - Zelfs als
scrollbar-widthis toegepast, geven macOS-overlayscrollbalken de track (goot) standaard transparant weer. Als het ontwerp een zichtbare achtergrondkleur voor de track vereist op MacOS, MOET jescrollbar-gutter: stable;toepassen op de scrollbare container. Houd er rekening mee dat deze alleen verschijnt nadat de gebruiker de cursor op de scrollbalk heeft geplaatst. - Zelfs met
scrollbar-gutter: stablekan de track transparant zijn op MacOS. De duim mag niet afhankelijk zijn van de trackkleur om zichtbaar te zijn.
Verdere aanpassing
De meeste browser-UI's bieden pseudo-elementen om de weergave volledig aan te passen, zoals:
::placeholder::spelling-error::grammar-error::selection::search-text::target-text::file-selector-button
Je kunt light-dark()-kleuren gebruiken voor elk van deze elementen om kleuren toe te passen die zich aanpassen aan het gebruikte kleurenschema.
4. Verschillende afbeeldingen voor de lichte en donkere modus
Voor CSS-afbeeldingen kan light-dark() ook worden gebruikt om verschillende afbeeldingswaarden te bieden.
BELANGRIJK: Beide waarden in light-dark() moeten van hetzelfde type zijn. Je kunt een kleur niet combineren met een afbeelding.
Als een van de 2 een afbeelding moet zijn, gebruik je image(<color>) om de kleurwaarde te verpakken.
Op JS gebaseerde themadetectie
De meeste vertakkingen van kleurenschema's moeten worden uitgevoerd in CSS, die zich automatisch aanpast aan wijzigingen.
Elke JS die matchMedia("(prefers-color-scheme: dark)").matches leest, MOET ook de gebeurtenis change verwerken, omdat de systeemvoorkeur op elk moment kan veranderen.
OPTIONEEL: Een schakelaar voor kleurenschema's implementeren
Als je gebruikers wilt toestaan de systeemstandaard voor deze site handmatig te overschrijven, kun je een schakelaar voor de donkere modus implementeren. De meeste sites hebben geen permanente schakelaar nodig in de UI van de site. Meestal is het voldoende om standaard het kleurenschema van het systeem te gebruiken, eventueel met een instelling in een afzonderlijk instellingenscherm. Ga naar Schakelaars voor de donkere modus voor best practices voor de implementatie van een schakelaar voor de donkere modus (permanent of niet).
OPTIONEEL: Componentspecifieke overschrijvingen
Je kunt het algemene thema voor specifieke elementen overschrijven door color-scheme in te stellen.
Ga naar Componentspecifieke lichte/donkere thema's voor meer informatie en valkuilen.
Bekende problemen om rekening mee te houden
Problemen om rekening mee te houden als je color-scheme gebruikt
- Chrome en Firefox respecteren
color-schemevoor iframes: ze geven ingesloten pagina's weer in het juiste kleurenschema en passen de mediaqueryprefers-color-schemevan de ingesloten pagina aan decolor-schemevan de insluitingscontext aan. Safari doet dit niet en herleidtprefers-color-schemenaar de systeeminstelling, zelfs binnen iframes.- Als je zowel de bovenliggende pagina als het iframe beheert: Geef het kleurenschema van de bovenliggende pagina expliciet door aan het iframe, via een URL-parameter (
?theme=dark) op het moment dat het iframe wordt gemaakt of viapostMessage()(waarmee je ook kunt reageren op wijzigingen tijdens de runtime). Stel in het iframe een klasse in op<html>(en/ofcolor-schemeop:root) op basis van dat signaal in plaats van te vertrouwen opprefers-color-scheme. - Als je alleen de ingesloten pagina beheert: Er is geen betrouwbare manier om de
color-schemevan de insluitingscontext te detecteren vanuit het iframe in Safari. Maak een expliciete themaparameter beschikbaar in je insluit-API (bijvoorbeeld een querytekenreeks ofpostMessage-protocol) en documenteer deze voor insluiters.
- Als je zowel de bovenliggende pagina als het iframe beheert: Geef het kleurenschema van de bovenliggende pagina expliciet door aan het iframe, via een URL-parameter (
Reservestrategieën
Fallbacks en browserondersteuning voor kleurenschema
De property color-scheme is progressive enhancement.
Browsers die dit niet ondersteunen, negeren deze property en gebruiken de standaard UI voor de lichte modus.
Als je je wilt aanpassen aan de voorkeuren van de gebruiker in oudere browsers, gebruik je prefers-color-scheme-mediaquery's om verschillende kleuren te bieden als de donkere modus de voorkeur heeft.
- Gebruik de mediaquery om aangepaste eigenschappen aan te zetten op
:rootofhtml. - Gebruik de mediaquery niet voor afzonderlijke componenten, tenzij de component een heel specifiek type aanpassing voor de donkere modus vereist dat verder gaat dan kleuren.
: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 en browserondersteuning voor light-dark()
Voor browsers die color-scheme ondersteunen maar nog niet light-dark(), moeten lichte en donkere versies van kleuren eerst worden gedefinieerd als aangepaste eigenschappen. De mediaquery prefers-color-scheme moet worden gebruikt om kleuren in te stellen voor de betreffende modus, zoals in het voorbeeld hieronder:
: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 en browserondersteuning voor light-dark() afbeeldingswaarden
Voor browsers die light-dark() niet ondersteunen voor afbeeldingen, gebruik je image-set() als schakelaar:
geef elke optie een type() van een aangepaste eigenschap en stel de inactieve optie in op een niet-ondersteund MIME-type, zodat de browser die optie negeert.
De actieve optie krijgt een lege waarde, dus het is een gewone image-set()-optie zonder type().
Definieer de schakelaar één keer op :root. Elke gebruikssite heeft dan alleen beide afbeeldingen inline nodig, zoals 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));
}
}
- Alleen de geselecteerde afbeelding wordt gedownload.
- Oplossingen werken nog steeds:
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)). - Gebruik NIET
type("")voor de actieve optie. Browsers behandelen de lege tekenreeks als niet-ondersteund en verwijderen elke optie. - In tegenstelling tot
light-dark()volgt de schakelaar niet decolor-schemedie is ingesteld voor een substructuur. Een handmatige schakelaar of een substructuur diecolor-schemeinstelt, MOET ook--light-typeen--dark-typeomdraaien.
Alternatief: één aangepaste eigenschap per afbeelding
Dit is eenvoudiger als er maar een paar afbeeldingen variëren, maar elke afbeelding heeft een eigen mediaquery-vertakking nodig en een handmatige schakelaar moet elke afbeelding omdraaien.
: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 en browserondersteuning voor image()
Gebruik een kleurovergang met één kleurpunt en geen posities, bijvoorbeeld linear-gradient(blue).
Voor bredere browserondersteuning kun je expliciet 0 100% posities invoeren voor de enkele kleurovergang, bijvoorbeeld linear-gradient(blue 0 100%).
Fallbacks en browserondersteuning voor scrollbar-color
Deze functie is een progressive enhancement en vereist niet altijd fallbacks.
Als de stijl belangrijk is en het Baseline-doel van de gebruiker Baseline Algemeen beschikbaar of eerder is, MOET je de niet-standaard pseudo-elementen ::-webkit-scrollbar opnemen als fallbacks.
Plaats verouderde fallbacks in een @supports not (scrollbar-color: auto)-blok om conflicten te voorkomen tussen standaardproperty's en verouderde WebKit-selectors in browsers die beide systeemeigen ondersteunen.
Als u aangepaste eigenschappen gebruikt om kleuren te definiëren, worden deze automatisch overgenomen door de verouderde WebKit-selectors. U hoeft ze NIET te dupliceren.
/* 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 en browserondersteuning voor accent-color
De property accent-color is progressive enhancement.
Browsers die deze property niet ondersteunen, negeren deze en gebruiken de standaard UI-kleuren.