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 Trybem ciemnym

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

W przypadku trybu ciemnego wróciliśmy do punktu wyjścia. Na początku przetwarzania danych osobowych tryb ciemny nie był kwestią wyboru, ale w rzeczywistości: monochromatyczne monitory komputerowe CRT pracowały przez wypalanie wiązek elektronów na ekranie fosforzowym, a fosfor używany we wczesnych urządzeniach CRT miał kolor zielony. Tekst był wyświetlany na zielono, a reszta ekranu była czarna, dlatego te modele były często nazywane zielonymi ekranami.

Ciemno-białe edytowanie tekstu
Czarny na białym (źródło)

Wprowadzone później kolorowe CRT zawierały czerwone, zielone i niebieskie fosfory w różnych kolorach. 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.

Czarne na białym w przeglądarce WorldWideWeb
Przeglądarka WorldWideWeb (Source)

To właśnie wtedy zapoczątkował trend wzornictwa ciemny na białym, który przeniósł się do początków internetu opartych na dokumentach. Pierwsza w historii przeglądarka – WorldWideWeb – (pamiętaj, że nie wynaleziono jeszcze nawet stylu CSS) w ten sposób wyświetlała strony internetowe. Ciekawostka: druga w historii przeglądarka, Line Mode Browser, czyli przeglądarka działająca na terminalu, wyświetlała się w ciemnym kolorze. 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 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 łatwiejsze w obsłudze komputery, tablety i smartfony doprowadziły do 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 ciemnych 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 zadajemy 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. Apple w dokumentacji dla programistów korzystających z trybu ciemnego wyraźnie pisze: „Podjęcie decyzji o tym, czy włączyć wygląd jasnego czy ciemnego, jest estetyczne dla większości użytkowników i może nie mieć związku z oświetleniem 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śniejszym wystąpieniem takiego narzędzia ułatwień dostępu, jakie udało mi się znaleźć, jest funkcja CloseView w Systemie 7, która miała przełącznik Black on White i White on Black (Czarny na białym). 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 stylów 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). Definiuje się go jako „połączenie problemów ze wzrokiem i widzeniem związanych z korzystaniem z 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ę barw 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

Warto też wspomnieć, że tryb ciemny pozwala zaoszczędzić znaczną energię 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. Poziom zapytań o multimedia na poziomie 5 wprowadza tak zwane funkcje multimedialne związane z preferencjami użytkownika, które pozwalają witrynom wykrywać preferowany sposób wyświetlania treści przez użytkownika.

Funkcja mediów prefers-color-scheme służy do wykrywania, czy użytkownik poprosił o użycie 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 raportowany w wyniku zapytania o multimedia, więc możesz łatwo sprawdzić, czy bieżąca przeglądarka obsługuje ten tryb – wystarczy, że to zapytanie w ogóle prefers-color-scheme będzie pasować. 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 ustawieniach użytkownika w momencie żą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

Na koniec 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 użytkownicy nie używają obecnie. 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 kodzie źródłowym (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 ciemny na jasnym oraz jasny 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.

Ta wartość 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 podświetlenia zależnego od motywu. Szczegółowe informacje o elemencie color-scheme znajdziesz w module dostosowania 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 użyj 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 filmie z Glitch znajdziesz kompletny przykład, który pokazuje, jak stosować omówione wyżej zagadnienia 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 CSS z najniższym priorytetem w trybie ciemnym.
Schemat wczytywania sieci pokazujący, jak w trybie ciemnym CSS wczytywa się z najniższym priorytetem
Witryna w trybie ciemnym wczytuje CSS w trybie jasnym o najniższym priorytecie.
Schemat wczytywania sieci pokazujący, jak w domyślnym trybie jasnym CSS wczytywany w trybie ciemnym jest ładowany z najniższym priorytetem
Witryna w domyślnym trybie jasnym w przeglądarce, która nie obsługuje prefers-color-scheme, wczytuje 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. Za jej pomocą możesz na przykład dynamicznie zmieniać favikonę strony lub zmienić <meta name="theme-color">, który określa kolor paska adresu URL w Chrome. W pełnym przykładzie powyżej widać, jak to wygląda w praktyce. Aby zobaczyć zmiany koloru motywu i favikony, otwórz wersję demonstracyjną w 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

Emuluję prefers-color-scheme w Narzędziach deweloperskich

Przełączanie schematów kolorów całego systemu operacyjnego może być irytujące. Dlatego w Narzędziach deweloperskich w Chrome możesz teraz emulować preferowany schemat kolorów użytkownika w sposób wpływający tylko na aktualnie widoczną kartę. 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

Zrzuty ekranu prefers-color-scheme w 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 dostępny jest skrypt Puppeteer, który pozwala tworzyć zrzuty ekranu stron w trybie ciemnym i jasnym. Możesz uruchomić ten skrypt jednorazowo lub dodać 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 korzystania z trybu ciemnego

Unikaj czystej bieli.

Małym szczegółem, który zauważyliście, 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ęć.

Jeśli porównasz 2 zrzuty ekranu poniżej, zauważysz, że nie tylko podstawowy motyw zmienił się z ciemnego w jasnym na jasny w ciemnym, ale również trochę się zmienił. Z moich badań opinii użytkowników wynika, że większość ankietowanych osób woli mniej żywe i atrakcyjne obrazy w trybie ciemnym. Nazywam to ponownym zabarwieniem.

Obraz banera powitalnego jest nieco przyciemniony w trybie ciemnym.
Baner powitalny w trybie ciemnym, nieco przyciemniony.
Zwykły baner powitalny 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. Chcę w ten sposób zmienić kolorystykę grafik wektorowych (ikon) w inny sposób niż w przypadku zdjęć. Więcej informacji 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 funkcja 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ść 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 ludzie nie lubią odwracania zdjęć, ale ta metoda sprawdza się w przypadku większości ikon. 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.
Zwykłe ikony w trybie jasnym.
Zwykłe 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 filtrów inwersji możesz użyć słowa kluczowego CSS currentColor, które reprezentuje wartość właściwości color elementu. Pozwala to używać wartości color w usługach, które nie otrzymują 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 stosowany w kontekście. Pamiętaj, że ta metoda działa tylko w przypadku wstawionych lub <use href="…"> plików SVG, ale nie w przypadku plików SVG, które są używane jako src obrazu lub w jakiś sposób za pomocą CSS. Sposób wdrożenia tych zmian widać w poniższej wersji demonstracyjnej.

<!-- 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);
}

Kierunek sztuki 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 przypadku internetu kierunek w sztuce odpowiada za ogólny wygląd strony i to, w jaki sposób komunikuje się wizualnie, stymuluje nastrój, kontrastuje z różnymi cechami i podoba się psychicznie dla docelowych odbiorców.

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, we wszystkich pozostałych przypadkach domyślnie jest używana 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. Ma nazwę <dark-mode-toggle> i dodaje na stronie przełącznik (tryb ciemny: wł./wył.) 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 wkradło się w wszystkie pozostałe przykłady 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.
z przełącznikiem 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 sterującym, 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 wpisu:

Podziękowania

Funkcja mediów prefers-color-scheme, właściwość CSS color-scheme oraz powiązany tag meta zostały zaimplementowane przez 👏 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.