Właściwość color-scheme wskazuje, które schematy kolorów (np. jasny lub ciemny) obsługuje Twoja strona. Informuje to przeglądarkę, że może automatycznie dostosowywać motywy natywnych elementów interfejsu, takich jak paski przewijania, elementy sterujące formularzy i domyślne tło obszaru roboczego, do projektu witryny i pomaga zminimalizować białe błyski podczas początkowego ładowania.
Implementacja
1. Deklarowanie obsługiwanych schematów w kodzie HTML
OBOWIĄZKOWE: aby zapobiec „mignięciu treści bez motywu” (FOUC), umieść tag <meta> w sekcji <head>, aby przeglądarka wiedziała, które motywy obsługujesz, zanim jeszcze zacznie renderowanie. Chociaż ten tag <meta> pomaga uniknąć FOUC przez wczesne ustawienie początkowego koloru obszaru roboczego, może nie całkowicie wyeliminować migotanie we wszystkich przeglądarkach lub warunkach wczytywania.
<!-- MANDATORY: Declare support for both light and dark themes -->
<meta name="color-scheme" content="light dark">
2. Zastosuj schemat kolorów na całej stronie do elementu :root lub html w CSS
OBOWIĄZKOWO: zastosuj właściwość color-scheme do elementu html lub pseudoklasy :root. Przeglądarki sprawdzają element główny, aby określić motyw dla całego widocznego obszaru, w tym paski przewijania elementu głównego i początkowe tło „obszaru roboczego”. Jeśli zastosujesz je tylko do elementu body, te globalne interfejsy mogą pozostać w trybie jasnym, ponieważ element body nie kontroluje kontekstu renderowania okna.
/* 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. Definiowanie tokenów kolorów jasnych i ciemnych
Możesz użyć funkcji light-dark(), aby zdefiniować tokeny kolorów, które automatycznie dostosowują się do różnych wartości color-scheme.
Zalecamy też zachowanie nieprzetworzonych wartości kolorów w osobnych właściwościach niestandardowych, co ułatwia ich łączenie na różne sposoby (oraz ułatwia działanie kreacji zastępczej, jeśli jest potrzebna).
Aby mieć większą kontrolę nad kolorami wbudowanego interfejsu, np. accent-color lub scrollbar-color, autorzy mogą opcjonalnie dodawać własne kolory dynamiczne za pomocą właściwości niestandardowych lub funkcji light-dark(). Ta funkcja automatycznie wybiera prawidłowy kolor na podstawie obliczonego color-scheme elementu i eliminuje potrzebę stosowania zbędnych zapytań o media, ale nie jest wymagana w przypadku podstawowej implementacji.
: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);
}
OPCJONALNIE: dostępnych jest wiele kolorów systemowych, które automatycznie dostosowują się do używanego schematu kolorów (i innych trybów kolorów, np. wymuszonych kolorów), takich jak canvas, canvastext, accentcolor (sprawdź obsługę), buttonborder itp. Zwykle są one zbyt ograniczone, aby były przydatne, poza bardzo konkretnymi przypadkami, gdy musisz dokładnie dopasować określony domyślny interfejs przeglądarki lub jako wartości zastępcze/domyślne.
OPCJONALNIE: dostosuj pary kolorów do kontekstu
Nawet w przypadku zastępowania ustawienia domyślnego systemu przydatne może być użycie zapytania o media prefers-color-scheme do zdefiniowania różnych par kolorów, które uwzględniają kolory przeglądarki i interfejsu systemu operacyjnego wokół strony (lub otaczającej strony, gdy strona jest używana jako element iframe).
Możesz na przykład użyć nieco ciemniejszego jasnego motywu, gdy ustawienie systemowe to dark, lub bardziej kontrastowego ciemnego motywu, gdy ustawienie systemowe to light, aby strona nie była wizualnie przytłoczona przez otaczający interfejs.
Szczegółowe dostosowywanie interfejsu przeglądarki
Ustawienie color-scheme już dostosowuje interfejs przeglądarki do używanego schematu kolorów, ale używa domyślnych ustawień systemu operacyjnego lub kolorów systemowych, które mogą nie pasować idealnie do projektu witryny.
Nowoczesne przeglądarki udostępniają kilka precyzyjnych punktów zaczepienia dostosowywania tych elementów.
Nie implementuj ponownie elementów sterujących tylko po to, aby dostosować ich wygląd, bez wyczerpania możliwości dostosowywania, które zapewniają nowoczesne przeglądarki.
Ustawianie koloru uzupełniającego
Niektóre elementy interfejsu przeglądarki (np. zaznaczone pola wyboru lub suwaki) używają koloru uzupełniającego.
Domyślnie jest to ustawienie systemu operacyjnego, ale możesz użyć właściwości accent-color, aby ustawić kolor, który lepiej pasuje do strony, np. kolor marki.
html {
accent-color: light-dark(var(--color-accent-light), var(--color-accent-dark));
}
Problemy, o których warto pamiętać podczas używania właściwości accent-color
Renderowanie accent-color w przeglądarce może się różnić.
W przypadku wskaźników, które są zwykle wyświetlane na tle w kolorze uzupełniającym, takich jak znaczniki pól wyboru i kropki przycisków opcji, przeglądarki mogą stosować różne rozwiązania:
- Chromium i Firefox zwykle wybierają kontrastowy kolor wskaźnika.
- Safari może zachować biały wskaźnik w trybie jasnym lub czarny wskaźnik w trybie ciemnym, zmieniając kolor uzupełniający za nim. Ta korekta nie zawsze zapewnia wystarczający kontrast dla każdego podanego koloru, dlatego przetestuj ważne kombinacje w Safari, w tym zarówno jasne, jak i ciemne schematy kolorów. Nie zakładaj, że Safari automatycznie wybierze kolor wskaźnika, który zapewnia najlepszy kontrast.
Kolory paska przewijania
Możesz używać scrollbar-color razem z light-dark(), aby ustawiać niestandardowe kolory paska przewijania, które dostosowują się do używanego schematu kolorów.
: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);
}
Problemy, o których warto pamiętać podczas używania właściwości scrollbar-color
- NIE animuj ani nie zmieniaj
scrollbar-color. Błąd WebKit powoduje migotanie paska przewijania przy każdej zmianiescrollbar-color. - W systemie macOS właściwości
scrollbar-color(standardowe) i::-webkit-scrollbar(starsze) są domyślnie ignorowane, ponieważ system macOS używa natywnych pasków przewijania „nakładki”. MUSISZ połączyć spersonalizowane kolory zscrollbar-width(np.thinlubauto), aby wymusić ich renderowanie w systemie macOS. - Nawet po zastosowaniu właściwości
scrollbar-widthnakładane paski przewijania w systemie macOS domyślnie renderują ścieżkę (rynienkę) jako przezroczystą. Jeśli projekt wymaga widocznego koloru tła ścieżki w systemie macOS, MUSISZ zastosowaćscrollbar-gutter: stable;do kontenera z możliwością przewijania, ale pamiętaj, że pojawi się on dopiero po najechaniu kursorem na pasek przewijania. - Nawet przy ustawieniu
scrollbar-gutter: stableścieżka może być przezroczysta w systemie MacOS. Widoczność suwaka nie powinna zależeć od koloru ścieżki.
Dalsze dostosowywanie
Większość interfejsów przeglądarek udostępnia pseudoelementy, które umożliwiają pełne dostosowanie wyglądu, np.:
::placeholder::spelling-error::grammar-error::selection::search-text::target-text::file-selector-button
Możesz użyć kolorów light-dark(), aby zastosować kolory, które dostosowują się do używanego schematu kolorów.
4. różne obrazy w trybie jasnym i ciemnym;
W przypadku obrazów CSS można też użyć light-dark(), aby podać różne wartości obrazu.
WAŻNE: obie wartości w parametrze light-dark() muszą być tego samego typu. Nie możesz połączyć koloru z obrazem.
Jeśli jeden z tych elementów musi być obrazem, użyj image(<color>), aby opakować wartość koloru.
Wykrywanie motywu na podstawie JS
Większość rozgałęzień schematu kolorów powinna być wykonywana w kodzie CSS, który automatycznie dostosowuje się do zmian.
Każdy kod JS odczytujący matchMedia("(prefers-color-scheme: dark)").matches MUSI też obsługiwać zdarzenie change, ponieważ preferencje systemowe mogą się zmienić w każdej chwili.
OPCJONALNIE: implementowanie przełącznika schematu kolorów
Jeśli chcesz zezwolić użytkownikom na ręczne zastępowanie domyślnego ustawienia systemu w przypadku tej witryny, możesz wdrożyć przełącznik trybu ciemnego. Większość witryn nie potrzebuje stałego przełącznika w interfejsie. Zwykle wystarczy domyślny schemat kolorów systemu, opcjonalnie z ustawieniem na osobnym ekranie ustawień. Sprawdzone metody implementacji przełącznika trybu ciemnego (trwałego lub nie) znajdziesz w sekcji Przełączniki trybu ciemnego.
OPCJONALNIE: zastąpienia dotyczące komponentów
Możesz zastąpić motyw globalny w przypadku określonych elementów, ustawiając w nich color-scheme.
Więcej informacji i wskazówek znajdziesz w sekcji Jasne i ciemne motywy dla poszczególnych komponentów.
Znane problemy, o których warto wiedzieć
Problemy, o których warto pamiętać podczas korzystania ze schematu kolorów
- Chrome i Firefox respektują
color-schemew przypadku elementów iframe: renderują umieszczone strony w odpowiednim schemacie kolorów i dostosowują zapytanie o mediaprefers-color-schemeumieszczonej strony, aby odzwierciedlićcolor-schemekontekstu umieszczenia. Safari nie obsługuje tej funkcji i rozpoznajeprefers-color-schemejako ustawienie systemowe nawet w elementach iframe.- Jeśli kontrolujesz zarówno element nadrzędny, jak i element iframe: przekaż schemat kolorów elementu nadrzędnego do elementu iframe – za pomocą parametru adresu URL (
?theme=dark) podczas tworzenia elementu iframe lub za pomocąpostMessage()(co pozwala też reagować na zmiany w czasie działania). W elemencie iframe ustaw klasę w<html>(lubcolor-schemew:root) na podstawie tego sygnału, zamiast polegać naprefers-color-scheme. - Jeśli masz kontrolę tylko nad umieszczoną stroną: nie ma niezawodnego sposobu na wykrycie
color-schemekontekstu umieszczenia z poziomu elementu iframe w Safari. Udostępnij jawny parametr motywu w interfejsie API do umieszczania (np. ciąg zapytania lub protokółpostMessage) i udokumentuj go dla osób umieszczających treści.
- Jeśli kontrolujesz zarówno element nadrzędny, jak i element iframe: przekaż schemat kolorów elementu nadrzędnego do elementu iframe – za pomocą parametru adresu URL (
Strategie zastępcze
Kreacje zastępcze i obsługa schematu kolorów w przeglądarce
Właściwość color-scheme to progresywne ulepszanie.
Przeglądarki, które nie obsługują tej właściwości, zignorują ją i będą używać domyślnego interfejsu w trybie jasnym.
Aby dostosować się do preferencji użytkownika w starszych przeglądarkach, użyj zapytań o multimedia prefers-color-scheme, aby wyświetlać różne kolory, gdy preferowany jest tryb ciemny.
- Używaj zapytania o media, aby przełączać właściwości niestandardowe w
:rootlubhtml. - Unikaj używania zapytania o media w przypadku poszczególnych komponentów, chyba że komponent wymaga bardzo konkretnego typu dostosowania trybu ciemnego, który nie ogranicza się do kolorów.
: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);
}
Zastępcze i obsługa funkcji light-dark() w przeglądarkach
W przypadku przeglądarek, które obsługują color-scheme, ale nie obsługują jeszcze light-dark(), jasne i ciemne wersje kolorów należy najpierw zdefiniować jako właściwości niestandardowe, a zapytanie o media prefers-color-scheme powinno służyć do ustawiania kolorów dla odpowiedniego trybu, jak w przykładzie poniżej:
: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);
}
Wartości zastępcze i obsługa wartości obrazu light-dark() w przeglądarkach
W przypadku przeglądarek, które nie obsługują light-dark() dla obrazów, użyj image-set() jako przełącznika:
nadaj każdej opcji type() z właściwości niestandardowej i ustaw nieaktywną opcję na nieobsługiwany typ MIME, aby przeglądarka odrzuciła tę opcję.
Aktywna opcja otrzymuje pustą wartość, więc jest to zwykła opcja image-set() bez type().
Zdefiniuj przełącznik raz na urządzeniu :root. W każdym miejscu użycia wystarczy wtedy umieścić oba obrazy w tekście, np. 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));
}
}
- Pobierany jest tylko wybrany obraz.
- Rozdzielczości, które nadal działają:
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)). - NIE używaj
type("")w przypadku opcji aktywnej. Przeglądarki traktują pusty ciąg znaków jako nieobsługiwany i odrzucają wszystkie opcje. - W przeciwieństwie do
light-dark()przełącznik nie uwzględnia ustawieniacolor-schemew poddrzewie. Ręczne przełączenie lub dowolne poddrzewo, które ustawiacolor-scheme, MUSI również przełączać--light-typei--dark-type.
Alternatywa: 1 właściwość niestandardowa na obraz
Jest to prostsze, gdy tylko kilka obrazów się różni, ale każdy obraz wymaga własnej gałęzi zapytania o media, a każdy z nich musi być przełączany ręcznie.
: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);
}
Kreacje zastępcze i obsługa funkcji image() w przeglądarce
Użyj gradientu z jednym punktem koloru i bez pozycji, np. linear-gradient(blue).
Aby zapewnić obsługę w większej liczbie przeglądarek, możesz wyraźnie podać 0 100% pozycje dla pojedynczego punktu koloru, np. linear-gradient(blue 0 100%).
Zastępcze i obsługiwane przez przeglądarki kolory paska przewijania
Ta funkcja jest progresywnym ulepszeniem i nie zawsze wymaga kreacji zastępczych.
Jeśli styl jest ważny, a docelowa wersja Baseline użytkownika to „Baseline Widely Available” lub wcześniejsza, POWINNO się uwzględnić niestandardowe pseudoelementy ::-webkit-scrollbar jako kreacje zastępcze.
Umieść starsze kreacje zastępcze w bloku @supports not (scrollbar-color: auto), aby uniknąć konfliktów między właściwościami standardowymi a starszymi selektorami WebKit w przeglądarkach, które obsługują oba te rozwiązania.
Jeśli do definiowania kolorów używasz właściwości niestandardowych, zostaną one automatycznie zastosowane do starszych selektorów WebKit. NIE musisz ich duplikować.
/* 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);
}
}
Kreacje zastępcze i obsługa koloru uzupełniającego w przeglądarkach
Właściwość accent-color jest progresywnym ulepszaniem.
Przeglądarki, które nie obsługują tej właściwości, zignorują ją i użyją domyślnych kolorów interfejsu.