prefers-color-scheme: Witaj ciemności, mój stary przyjacielu

Przereklamowany czy niezbędny? Dowiedz się wszystkiego o trybie ciemnym i o tym, jak go obsługiwać, aby zapewnić użytkownikom wygodę.

Wprowadzenie

Tryb ciemny przed Dark Mode

Zielony ekran monitora komputerowego
Zielony ekran (źródło)

W przypadku trybu ciemnego wróciliśmy do punktu wyjścia. Na początku ery komputerów osobistych tryb ciemny nie był kwestią wyboru, lecz konieczności: monitory komputerowe CRT w kolorze monochromatycznym działały na zasadzie strzelania elektronami na ekranie fosforescencyjnym, a fosfor używany w wczesnych monitorach CRT był zielony. Tekst był wyświetlany na zielono, a reszta ekranu była czarna, dlatego te modele były często nazywane zielonymi ekranami.

Edytowanie tekstu w ciemnym kolorze na białym tle
Czarny na białym (źródło)

Wprowadzone później kolorowe monitory CRT wyświetlały różne kolory dzięki zastosowaniu fosforów czerwonego, zielonego i niebieskiego. Biały kolor uzyskano przez jednoczesne aktywowanie wszystkich trzech fosforów. Wraz z postępem bardziej zaawansowanych systemów WYSIWYG do publikacji na komputerze stała się popularna koncepcja tworzenia wirtualnych dokumentów przypominających fizyczny arkusz papieru.

Czarna strona na białym tle w przeglądarce WorldWideWeb
Przeglądarka WorldWideWeb (Source)

Właśnie wtedy pojawiła się tendencja do ciemnego tekstu na białym tle, która została przeniesiona do wczesnych stron internetowych opartych na dokumentach. Pierwszy w historii przeglądarka, WorldWideWeb (pamiętaj, że CSS nie istniała jeszcze w tym czasie), wyświetlała strony w ten sposób. Ciekawostka: druga przeglądarka w historii, Line Mode Browser, czyli przeglądarka oparta na terminalu, była zielona na ciemnym tle. Obecnie strony internetowe i aplikacje internetowe są zwykle projektowane z ciemnym tekstem na jasnym tle. Jest to założenie podstawowe, które jest również zakodowane na stałe w stiliszczach plików klienta użytkownika, w tym w Chrome.

Smartfon używany podczas leżenia w łóżku
Smartfon używany w łóżku (źródło: Unsplash)

Czasy CRT już dawno minęły. Konsumpcja i tworzenie treści przeniosły się na urządzenia mobilne z podświetlanymi ekranami LCD lub energooszczędnymi ekranami AMOLED. Mniejsze i bardziej przenośne komputery, tablety i smartfony spowodowały pojawienie się nowych wzorców użytkowania. Zajęcia rekreacyjne, takie jak przeglądanie internetu, kodowanie dla zabawy i zaawansowane gry, często odbywają się po godzinach pracy w słabo oświetlonych pomieszczeniach. Użytkownicy korzystają z urządzeń nawet w łóżku. Im więcej osób używa urządzeń w ciemności, tym bardziej popularna staje się koncepcja jasne na ciemnym tle.

Dlaczego tryb ciemny

Tryb ciemny ze względów estetycznych

Gdy zadamy użytkownikom pytanie o to, dlaczego lubią tryb ciemny lub chcą z niego korzystać, najczęściej odpowiadają, że jest on łagodniejszy dla oczu, a zaraz potem, że jest elegancki i ładny. W dokumentacji dla deweloperów na temat trybu ciemnego Apple wyraźnie stwierdza: „Wybór jasnego lub ciemnego wyglądu jest kwestią estetyki dla większości użytkowników i może nie mieć związku z warunkami oświetlenia otoczenia”.

CloseView w systemie Mac OS 7 z
System 7 CloseView (Source)

Tryb ciemny jako narzędzie ułatwień dostępu

Są też osoby, które potrzebują ciemnego trybu i używają go jako kolejnego narzędzia ułatwiającego dostępność, na przykład użytkownicy słabowidzący. Najwcześniejsze wystąpienie takiego narzędzia ułatwień dostępu, jakie udało mi się znaleźć, to funkcja CloseViewsystemie 7, która zawierała przełącznik Czarny na białymBiały na czarnym. System 7 obsługiwał kolory, ale domyślny interfejs użytkownika był nadal czarno-biały.

Po wprowadzeniu kolorów okazało się, że te implementacje oparte na odwróceniu obrazu mają swoje słabości. Badania użytkowników przeprowadzone przez Szpiro et al. na temat korzystania z urządzeń komputerowych przez osoby niedowidzące wykazały, że wszyscy przepytani użytkownicy nie lubią odwróconych obrazów, ale wielu z nich woli jasny tekst na ciemnym tle. Apple uwzględnia tę preferencję użytkownika dzięki funkcji inteligentnego odwracania kolorów, która odwraca kolory na wyświetlaczu, z wyjątkiem obrazów, multimediów i niektórych aplikacji, które używają ciemnych kolorów.

Specyficzną formą upośledzenia wzroku jest zespół objawów związanych z używaniem komputerów (w tym komputerów stacjonarnych, laptopów i tabletów) oraz innych wyświetlaczy elektronicznych (np.smartfonów i elektronicznych urządzeń do czytania), który określa się jako zespół objawów związanych z używaniem komputerów (w tym komputerów stacjonarnych, laptopów i tabletów) oraz innych wyświetlaczy elektronicznych (np. smartfonów i elektronicznych urządzeń do czytania). Zakłada się, że korzystanie przez nastolatków z urządzeń elektronicznych, zwłaszcza w nocy, zwiększa ryzyko krótszego snu, wydłuża czas potrzebny na zaśnięcie i pogłębia niedobór snu. Dodatkowo według raportów ekspozycja na niebieskie światło wpływa na regulację rytmu dobowego i cyklu snu, a nieregularne oświetlenie może prowadzić do braku snu, co może wpływać na nastrój i wykonanie zadań. Naukowcy z Rosenfield Aby ograniczyć te negatywne skutki, warto zmniejszyć ilość niebieskiego światła, dostosowując temperaturę barwową wyświetlacza za pomocą funkcji takich jak Night Shift w iOS lub Night Light w Androidzie. Warto też unikać jasnego światła i nieregularnego światła, korzystając z ciemnych motywów lub trybów ciemnego wyświetlacza.

Oszczędzanie energii dzięki trybowi ciemnemu na ekranach AMOLED

Poza tym tryb ciemny pozwala oszczędzać dużo energii na ekranach AMOLED. Badania przypadków dotyczące Androida, które koncentrowały się na popularnych aplikacjach Google, takich jak YouTube, wykazały, że oszczędności energii mogą sięgać nawet 60%. W filmie poniżej znajdziesz więcej informacji o tych przykładach i oszczędnościach energii w poszczególnych aplikacjach.

Aktywowanie trybu ciemnego w systemie operacyjnym

Teraz, gdy już wiesz, dlaczego tryb ciemny jest tak ważny dla wielu użytkowników, sprawdź, jak możesz go wspierać.

Ustawienia trybu ciemnego w Androidzie Q
Ustawienia ciemnego motywu w Androidzie Q

Systemy operacyjne, które obsługują tryb ciemny, zwykle mają opcję jego włączenia w ustawieniach. W macOS X ta opcja znajduje się w sekcji Ogólne w ustawieniach systemowych i ma nazwę Wygląd (zrzut ekranu). W Windows 10 ta opcja znajduje się w sekcji Kolory i ma nazwę Wybierz kolor (zrzut ekranu). W Androidzie Q znajdziesz go w sekcji Wyświetlacz jako przełącznik Ciemny motyw (zrzut ekranu). W iOS 13 możesz zmienić Wygląd w sekcji Wyświetlacz i jasność (zrzut ekranu).

Zapytanie o multimedia prefers-color-scheme

Jeszcze tylko teoria, zanim zacznę. Media queries pozwalają autorom testować i wyszukiwać wartości lub funkcje przeglądarki użytkownika lub wyświetlacza niezależnie od renderowanego dokumentu. Są one używane w regułach CSS @media do warunkowego stosowania stylów w dokumencie oraz w różnych innych kontekstach i językach, np. w HTML i JavaScript. Media Queries Level 5 wprowadza tak zwane funkcje multimediów preferowanych przez użytkownika, czyli sposób, w jaki witryny mogą wykrywać preferowany przez użytkownika sposób wyświetlania treści.

Funkcja mediów prefers-color-scheme służy do wykrywania, czy użytkownik zażądał użycia jasnego czy ciemnego motywu na stronie. Działa z tymi wartościami:

  • light: Wskazuje, że użytkownik poinformował system, że preferuje stronę z jasnym motywem (ciemny tekst na jasnym tle).
  • dark: Wskazuje, że użytkownik poinformował system, że woli stronę z ciemnym motywem (jasny tekst na ciemnym tle).

Obsługa trybu ciemnego

Sprawdzanie, czy przeglądarka obsługuje tryb ciemny

Tryb ciemny jest zgłaszany za pomocą zapytania o multimedia, więc możesz łatwo sprawdzić, czy bieżąca przeglądarka obsługuje tryb ciemny, sprawdzając, czy zapytanie o multimedia prefers-color-scheme pasuje. Zwróć uwagę, że nie podaję żadnej wartości, tylko sprawdzam, czy pasuje tylko zapytanie o multimedia.

if (window.matchMedia('(prefers-color-scheme)').media !== 'not all') {
  console.log('🎉 Dark mode is supported');
}

W momencie pisania tego tekstu prefers-color-scheme jest obsługiwana na komputerach i urządzeniach mobilnych (tam, gdzie jest dostępna) w Chrome i Edge w wersji 76, w Firefox w wersji 67 oraz w Safari w wersji 12.1 na macOS i w wersji 13 na iOS. W przypadku innych przeglądarek zapoznaj się z artykułem Czy mogę korzystać z tabel pomocy?.

Uzyskiwanie informacji o preferencjach użytkownika w momencie wysyłania żądania

Nagłówek wskazówki klienta Sec-CH-Prefers-Color-Scheme umożliwia witrynom opcjonalne pobieranie preferencji użytkownika dotyczących schematu kolorów w momencie wysyłania żądania, co pozwala serwerom wstawiać poprawny plik CSS inline i unikać wyświetlania nieprawidłowego motywu kolorów.

Tryb ciemny w praktyce

Zobaczmy, jak obsługa trybu ciemnego wygląda w praktyce. Podobnie jak w filmie Highlander, w przypadku trybu ciemnego może być tylko jeden: ciemny lub jasny, ale nigdy oba jednocześnie. Dlaczego to wspominam? Ponieważ ten fakt powinien mieć wpływ na strategię wczytywania. Nie zmuszaj użytkowników do pobierania kodu CSS na ścieżce renderowania krytycznego, która jest przeznaczona do trybu, którego obecnie nie używają. Aby zoptymalizować szybkość wczytywania, podzieliłem plik CSS przykładowej aplikacji, który zawiera te rekomendacje, na 3 części, aby opóźnić wczytywanie nieistotnego kodu CSS:

  • style.css, który zawiera reguły ogólne stosowane powszechnie w witrynie.
  • dark.css, który zawiera tylko reguły potrzebne do trybu ciemnego.
  • light.css, który zawiera tylko reguły potrzebne do trybu jasnego.

Strategia wczytywania

Te ostatnie, light.css i dark.css, są wczytywane warunkowo za pomocą zapytania <link media>. Początkowo nie wszystkie przeglądarki będą obsługiwać prefers-color-scheme (co można wykryć za pomocą wzorca powyżej). Rozwiązuję to dynamicznie, wczytując domyślny plik light.css za pomocą elementu <link rel="stylesheet"> wstawianego warunkowo w małym skrypcie wstawianym w tekście (wersja light jest wybrana arbitralnie, ale można też ustawić ciemną wersję jako domyślną). Aby uniknąć migania treści bez stylów, ukrywam zawartość strony, dopóki nie zostanie załadowany element light.css.

<script>
  // If `prefers-color-scheme` is not supported, fall back to light mode.
  // In this case, light.css will be downloaded with `highest` priority.
  if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
    document.documentElement.style.display = 'none';
    document.head.insertAdjacentHTML(
      'beforeend',
      '<link rel="stylesheet" href="/light.css" onload="document.documentElement.style.display = \'\'">',
    );
  }
</script>
<!--
  Conditionally either load the light or the dark stylesheet. The matching file
  will be downloaded with `highest`, the non-matching file with `lowest`
  priority. If the browser doesn't support `prefers-color-scheme`, the media
  query is unknown and the files are downloaded with `lowest` priority (but
  above I already force `highest` priority for my default light experience).
-->
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)" />
<link
  rel="stylesheet"
  href="/light.css"
  media="(prefers-color-scheme: light)"
/>
<!-- The main stylesheet -->
<link rel="stylesheet" href="/style.css" />

Architektura arkusza stylów

Korzystam z maksimum zmiennych CSS, dzięki czemu mój ogólny plik style.css jest właśnie ogólny, a wszystkie dostosowywanie do trybu jasnego lub ciemnego odbywa się w 2 pozostałych plikach dark.csslight.css. Poniżej możesz zobaczyć fragmenty rzeczywistych stylów, ale to powinno wystarczyć, aby przekazać ogólny zamysł. Deklaruję 2 zmienne, -⁠-⁠color-⁠-⁠background-color, które w podstawie tworzą motyw bazowy ciemny na jasnymjasny na ciemnym.

/* light.css: 👉 dark-on-light */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
}
/* dark.css: 👉 light-on-dark */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
}

W moim pliku style.css używam tych zmiennych w regułach body { … }. Są one zdefiniowane w pseudoklasie CSS :root – selektorze, który w kodzie HTML reprezentuje element <html> i jest identyczny z selektorem html, z tą różnicą, że jego specyficzność jest wyższa. Selektory te są używane kaskadowo, co pozwala mi deklarować globalne zmienne CSS.

/* style.css */
:root {
  color-scheme: light dark;
}

body {
  color: var(--color);
  background-color: var(--background-color);
}

W powyższym przykładzie kodu możesz zauważyć, że w usługi color-scheme wpisano wartość light dark oddzieloną spacjami.

Informuje przeglądarkę, jakie motywy kolorów obsługuje aplikacja, i pozwala jej aktywować specjalne warianty arkusza stylów użytkownika. Jest to przydatne np. do renderowania pól formularza z ciemnym tłem i jasnym tekstem, do dostosowywania pasków przewijania lub do włączania koloru wyróżnienia zależnego od motywu. Szczegółowe informacje o color-scheme znajdziesz w module do regulacji kolorów CSS na poziomie 1.

Reszta to tylko kwestia zdefiniowania zmiennych CSS dla elementów, które mają znaczenie w mojej witrynie. Semantyczne grupowanie stylów bardzo pomaga podczas pracy z ciemnym trybem. Na przykład zamiast -⁠-⁠highlight-yellow rozważ użycie zmiennej -⁠-⁠accent-color, ponieważ w trybie ciemnym kolor „żółty” może być w rzeczywistości nieżółty lub odwrotnie. Poniżej znajdziesz przykłady kilku dodatkowych zmiennych, których używam w tym przykładzie.

/* dark.css */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
  --link-color: rgb(0, 188, 212);
  --main-headline-color: rgb(233, 30, 99);
  --accent-background-color: rgb(0, 188, 212);
  --accent-color: rgb(5, 5, 5);
}
/* light.css */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
  --link-color: rgb(0, 0, 238);
  --main-headline-color: rgb(0, 0, 192);
  --accent-background-color: rgb(0, 0, 238);
  --accent-color: rgb(250, 250, 250);
}

Pełny przykład

W tym osadzonym klipie z Glitch możesz zobaczyć kompletny przykład, w którym omawiane wyżej zagadnienia są stosowane w praktyce. Spróbuj włączyć tryb ciemny w ustawieniach systemu operacyjnego i zobacz, jak zareaguje strona.

Wczytuję wpływ

Gdy zaczniesz testować ten przykład, zobaczysz, dlaczego wczytuję dark.css i light.css za pomocą zapytań o multimedia. Spróbuj włączyć tryb ciemny i ponownie załadować stronę: obecnie niepasujące arkusze stylów są nadal wczytywane, ale z najniższym priorytetem, dzięki czemu nigdy nie konkurują z zasobami, których strona potrzebuje w danym momencie.

Schemat wczytywania sieci pokazujący, jak w trybie jasnym wczytywanie szablonu CSS trybu ciemnego ma najniższy priorytet
Witryna w trybie jasnym wczytuje pliki CSS trybu ciemnego z najniższym priorytetem.
Schemat wczytywania sieci pokazujący, jak w trybie ciemnym wczytywanie szablonu CSS trybu jasnego ma najniższy priorytet
Witryna w trybie ciemnym wczytuje pliki CSS trybu jasnego z najniższym priorytetem.
Diagram wczytywania sieci pokazujący, jak w domyślnym trybie jasnym wczytywanie czcionki CSS trybu ciemnego ma najniższy priorytet
Witryna w domyślnym trybie jasnym w przeglądarce, która nie obsługuje prefers-color-scheme, wczytuje plik CSS trybu ciemnego z najniższym priorytetem.

Reakcja na zmiany trybu ciemnego

Podobnie jak w przypadku innych zmian zapytań o multimedia, zmiany w trybie ciemnym można subskrybować za pomocą JavaScriptu. Możesz na przykład dynamicznie zmieniać ikonę strony lub zmieniać <meta name="theme-color">, która określa kolor paska adresu w Chrome. Pełne przykłady powyżej pokazują to w akcji. Aby zobaczyć zmiany koloru motywu i favikony, otwórz demo na osobnej karcie.

const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkModeMediaQuery.addEventListener('change', (e) => {
  const darkModeOn = e.matches;
  console.log(`Dark mode is ${darkModeOn ? '🌒 on' : '☀️ off'}.`);
});

Od wersji Chromium 93 i Safari 15 możesz dostosowywać kolor na podstawie zapytania o multimedia z atrybutem media elementu koloru motywu meta. Wybrany zostanie pierwszy pasujący element. Możesz na przykład ustawić jeden kolor dla trybu jasnego, a inny dla trybu ciemnego. W momencie pisania tego artykułu nie można ich zdefiniować w pliku manifestu. Zobacz zgłoszenie na GitHubie w3c/manifest#975.

<meta
  name="theme-color"
  media="(prefers-color-scheme: light)"
  content="white"
/>
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />

Debugowanie i testowanie trybu ciemnego

Emulowanie prefers-color-scheme w Narzędziach deweloperskich

Zmiana schematu kolorów całego systemu operacyjnego może szybko stać się uciążliwa, dlatego narzędzia programistyczne Chrome umożliwiają teraz emulowanie preferowanego schematu kolorów użytkownika w taki sposób, aby dotyczył tylko widocznej karty. Otwórz menu poleceń, zacznij wpisywać Rendering, uruchom polecenie Show Rendering, a następnie zmień opcję Emuluj funkcję mediów CSS „prefers-color-scheme”.

Zrzut ekranu przedstawiający opcję „Emuluj funkcję mediów CSS prefers-color-scheme” na karcie Renderowanie w Narzędziach deweloperskich w Chrome

Zrzut ekranu prefers-color-scheme za pomocą Puppeteer

Puppeteer to biblioteka Node.js, która udostępnia interfejs API wysokiego poziomu do sterowania Chrome lub Chromium za pomocą protokołu DevTools. W dark-mode-screenshot udostępniamy skrypt Puppeteer, który umożliwia tworzenie zrzutów ekranu stron zarówno w ciemnym, jak i jasnym trybie. Możesz uruchomić ten skrypt jednorazowo lub włączyć go do zestawu testów ciągłej integracji (CI).

npx dark-mode-screenshot --url https://googlechromelabs.github.io/dark-mode-toggle/demo/ --output screenshot --fullPage --pause 750

Sprawdzone metody dotyczące trybu ciemnego

Unikaj czystej bieli.

Pewnym szczegółem, który możesz zauważyć, jest to, że nie używam czystej bieli. Aby uniknąć efektu świecenia i przeciekania na otaczający ciemny tekst, wybieram nieco ciemniejszy biały. Dobrze sprawdza się np. rgb(250, 250, 250).

przyciemniać i zmieniać kolorystykę zdjęć.

Porównując 2 zrzuty ekranu poniżej, zauważysz, że nie tylko motyw główny zmienił się z ciemny na jasnym tle na jasny na ciemnym tle, ale też obraz główny wygląda nieco inaczej. Moje badania użytkowników wykazały, że większość ankietowanych osób preferuje nieco mniej żywe i jasne obrazy, gdy aktywny jest tryb ciemny. Nazywam to ponownym zabarwieniem.

Obraz powitalny jest nieco przyciemniony w trybie ciemnym.
Baner powitalny w trybie ciemnym, nieco przyciemniony.
Zwykły obraz banera powitalnego w trybie jasnym.
Zwykły baner powitalny w jasnym trybie.

Zmiana kolorów może być osiągnięta za pomocą filtra CSS na moich obrazach. Używam selektora CSS, który pasuje do wszystkich obrazów, które nie mają .svg w swoim adresie URL. Chodzi o to, abym mógł nadać inną kolorystykę grafice wektorowej (ikonom) niż moim zdjęciom (fotografiom). Więcej informacji na ten temat znajdziesz w następnym akapicie. Zwróć uwagę, że ponownie używam zmiennej CSS, aby móc później elastycznie zmienić filtr.

Ponowne zabarwianie jest potrzebne tylko w trybie ciemnym, czyli gdy aktywna jest reguła dark.css. W regułach light.css nie ma odpowiednich reguł.

/* dark.css */
--image-filter: grayscale(50%);

img:not([src*='.svg']) {
  filter: var(--image-filter);
}

Dostosowywanie intensywności kolorów w ciemnym trybie za pomocą kodu JavaScript

Nie wszyscy są tacy sami i mają różne potrzeby dotyczące trybu ciemnego. Stosując opisaną powyżej metodę ponownego kolorowania, mogę łatwo ustawić intensywność skali szarości jako preferencję użytkownika, którą mogę zmienić za pomocą JavaScriptu. Ustawiając wartość 0%, mogę też całkowicie wyłączyć ponowne kolorowanie. Pamiętaj, że document.documentElement odwołuje się do elementu katalogu dokumentu, czyli tego samego elementu, do którego mogę się odwoływać za pomocą pseudoklasy :root CSS.

const filter = 'grayscale(70%)';
document.documentElement.style.setProperty('--image-filter', value);

Odwracanie grafiki wektorowej i ikon

W przypadku grafik wektorowych, które w moim przypadku są używane jako ikony odwołujące się do elementów <img>, używam innej metody zmiany koloru. Badania wykazały, że użytkownicy nie lubią odwróconych zdjęć, ale w przypadku większości ikon ta funkcja sprawdza się bardzo dobrze. Ponownie używam zmiennych CSS do określenia wartości odwrócenia w stanie normalnym i :hover.

Ikony są odwrócone w trybie ciemnym.
Ikony są odwrócone w trybie ciemnym.
Normalne ikony w trybie jasnym.
Ikony w trybie jasnym.

Zwróć uwagę, że ikony są odwrócone tylko w przypadku dark.css, a nie light.css, oraz że w tych 2 przypadkach ikona :hover ma inny stopień odwrócenia, aby była nieco ciemniejsza lub jaśniejsza w zależności od wybranego przez użytkownika trybu.

/* dark.css */
--icon-filter: invert(100%);
--icon-filter_hover: invert(40%);

img[src*='.svg'] {
  filter: var(--icon-filter);
}
/* light.css */
--icon-filter_hover: invert(60%);
/* style.css */
img[src*='.svg']:hover {
  filter: var(--icon-filter_hover);
}

Użyj currentColor do wstawiania plików SVG

W przypadku wbudowanych obrazów SVG zamiast używać filtrów odwrócenia możesz skorzystać ze słowa kluczowego currentColor w kodzie CSS, które reprezentuje wartość właściwości color elementu. Dzięki temu możesz używać wartości color w przypadku właściwości, które nie mają jej domyślnie. Jeśli jako wartość atrybutów SVG fill lub stroke zostanie użyta wartość currentColor, zostanie ona pobrana z wartości odziedkowej właściwości koloru. Co więcej, ta funkcja działa też w przypadku <svg><use href="…"></svg>, więc możesz mieć osobne zasoby, a currentColor będzie nadal stosowana w kontekście. Pamiętaj, że ta metoda działa tylko w przypadku wstawionych lub <use href="…"> plików SVG, ale nie plików SVG, do których odwołuje się src obrazu lub które są w jakiś sposób używane w CSS. Poniżej możesz zobaczyć, jak to działa w praktyce.

<!-- Some inline SVG -->
<svg xmlns="http://www.w3.org/2000/svg"
    stroke="currentColor"
>
  […]
</svg>

płynne przejścia między trybami;

Przejście z trybu ciemnego na jasny i odwrotnie może być płynne, ponieważ zarówno color, jak i background-coloranimowalnymi właściwościami CSS. Aby utworzyć animację, wystarczy zadeklarować 2 elementy transition dla 2 właściwości. Przykład poniżej ilustruje ogólną koncepcję. Możesz ją przetestować na żywo w prezentacji.

body {
  --duration: 0.5s;
  --timing: ease;

  color: var(--color);
  background-color: var(--background-color);

  transition: color var(--duration) var(--timing), background-color var(
        --duration
      ) var(--timing);
}

Kierowanie pracami nad projektem w trybie ciemnym

Z powodów związanych z wydajnością wczytywania zalecam, aby w atrybucie media elementów <link> (a nie w ramach stylów wstawianych w kod HTML) używać wyłącznie atrybutu prefers-color-scheme, ale są sytuacje, w których warto użyć atrybutu prefers-color-scheme bezpośrednio w kodzie HTML. Kierowanie pracami nad grafiką jest właśnie takim przypadkiem. W internecie reżyseria artystyczna zajmuje się ogólnym wyglądem strony i tym, jak przekazuje ona informacje wizualnie, stymuluje emocje, kontrastuje cechy i oddziałuje psychologicznie na odbiorców docelowych.

W przypadku trybu ciemnego to projektant decyduje, który obraz będzie najlepszy w danym trybie oraz czy przebarwianie obrazów nie jest wystarczająco dobre. Jeśli element <picture> jest używany, <source> wyświetlanego obrazu może zależeć od atrybutu media. W przykładzie poniżej półkula zachodnia jest wyświetlana w trybie ciemnym, a półkula wschodnia – w trybie jasnym. Jeśli nie ma preferencji, w wszystkich pozostałych przypadkach domyślnie jest wyświetlana półkula wschodnia. Jest to oczywiście tylko przykład. Przełącz tryb ciemny na urządzeniu, aby zobaczyć różnicę.

<picture>
  <source srcset="western.webp" media="(prefers-color-scheme: dark)" />
  <source srcset="eastern.webp" media="(prefers-color-scheme: light)" />
  <img src="eastern.webp" />
</picture>

Tryb ciemny, ale z opcją rezygnacji

Jak wspomnieliśmy w sekcji Dlaczego warto korzystać z ciemnego trybu, tryb ciemny jest dla większości użytkowników kwestią estetyki. W rezultacie niektórzy użytkownicy mogą preferować ciemny interfejs systemu operacyjnego, ale nadal chcą, aby strony internetowe były wyświetlane tak, jak są do tego przyzwyczajeni. Dobrym wzorcem jest początkowe stosowanie się do sygnału wysyłanego przez przeglądarkę (prefers-color-scheme), ale później opcjonalne zezwolenie użytkownikom na zastąpienie ustawień na poziomie systemu.

Element niestandardowy <dark-mode-toggle>

Możesz oczywiście utworzyć kod samodzielnie, ale możesz też użyć gotowego elementu niestandardowego (komponentu internetowego), który został przeze mnie stworzony właśnie w tym celu. Nazywa się ona <dark-mode-toggle> i dodaje do strony przełącznik (tryb ciemny: włącz/wyłącz) lub przełącznik motywu (jasny/ciemny), który możesz w pełni dostosować. Demo poniżej pokazuje element w akcji (a także 🤫 w sposób cichy w wszystkich pozostałych przykładach powyżej).

<dark-mode-toggle
  legend="Theme Switcher"
  appearance="switch"
  dark="Dark"
  light="Light"
  remember="Remember this"
></dark-mode-toggle>
przełączanie trybu ciemnego w trybie jasnym.
<dark-mode-toggle> w trybie jasnym.
przełączanie trybu ciemnego w trybie jasnym.
<dark-mode-toggle> w trybie ciemnym.

W poniżej zaprezentowanym poniżej demo kliknij elementy sterujące trybu ciemnego w prawym górnym rogu. Jeśli zaznaczysz pole wyboru w 3. i 4. elemencie sterowania, zobacz, jak wybrany tryb jest zapamięty nawet po ponownym załadowaniu strony. Dzięki temu użytkownicy mogą korzystać z ciemnego trybu w systemie operacyjnym, a Twoja witryna będzie wyświetlana w jasnym trybie lub odwrotnie.

Podsumowanie

Praca z ciemnym trybem i obsługa tego trybu jest przyjemna i otwiera nowe możliwości projektowe. Dla niektórych użytkowników może to oznaczać różnicę między niemożnością korzystania z Twojej witryny a zadowoleniem z jej korzystania. Tutaj trzeba uważać i koniecznie przeprowadzić dokładne testy, ale tryb ciemny to świetna okazja, aby pokazać, że zależy Ci na wszystkich użytkownikach. Dzięki sprawdzonym metodom opisanym w tym poście i elementowi niestandardowemu <dark-mode-toggle> możesz mieć pewność, że uda Ci się stworzyć niesamowity tryb ciemny. Daj nam znać na Twitterze, co udało Ci się stworzyć, i powiedz, czy ten wpis był przydatny. Możesz też przesłać sugestie dotyczące jego ulepszenia. Dziękujemy za uwagę! 🌒

Materiały dotyczące zapytania o multimedia: prefers-color-scheme

Materiały dotyczące tagu meta color-scheme i właściwości CSS:

Linki do ogólnych informacji o trybie ciemnym:

Artykuły z informacjami ogólnymi na potrzeby tego artykułu:

Podziękowania

Funkcja mediów prefers-color-scheme, właściwość CSS color-scheme oraz powiązany tag meta to implementacja autorstwa 👏 Rune Lillesveen. Rune jest też współredaktorem specyfikacji CSS Level 1 Module Color Adjustment. 🙏 Dziękuję Lukasz Zbylut, Rowan Merewood, Chirag Desai i Rob Dodson za dokładne sprawdzenie tego artykułu. Strategia wczytywania została opracowana przez Jake’a Archibalda. Emilio Cobos Álvarez wskazał mi prawidłową metodę wykrywania prefers-color-scheme. Wskazówka dotycząca odwołań do plików SVG i currentColor została przesłana przez Timothy’ego Hatchera. Na koniec dziękujemy wszystkim anonimowym uczestnikom różnych badań użytkowników, którzy pomogli nam sformułować rekomendacje zawarte w tym artykule. Obraz główny: Nathan Anderson.