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

Przesadnie budzące zainteresowanie czy konieczność? Dowiedz się wszystkiego o trybie ciemnym i o tym, jak go wykorzystać z korzyścią dla użytkowników.

Wstęp

Tryb ciemny przed trybem ciemnym

Zielone tło monitora komputerowego
Zielone tło (źródło)

W trybie ciemnym zatoczyliśmy koło. W czasach korzystania z komputerów osobistych tryb ciemny nie był kwestią wyboru, ale tak było w rzeczywistości: monochromatyczne monitory komputerowe CRT pracowały, uruchamiając wiązki elektronowe na ekranie fosforyzacyjnym, a fosfor używany we wczesnych monitorach CRT był zielony. Tekst był wyświetlany na zielono, a reszta ekranu była czarna, dlatego te modele były często określane jako zielone ekrany.

Ciemno-biały tryb edycji tekstu
Ciemnobiały (źródło)

Późniejsze modele kolorów Color CRT pokazały wiele kolorów dzięki wykorzystaniu fosforów czerwonego, zielonego i niebieskiego. Uzyskali biel, aktywując jednocześnie wszystkie 3 fosfory. Wraz z pojawieniem się bardziej wyrafinowanego edytora WYSIWYG publikowania na komputerze popularny stał się pomysł na to, aby wirtualny dokument przypominał kartkę papieru.

Ciemno-biała strona internetowa w przeglądarce WorldWideWeb
Przeglądarka WorldWideWeb (źródło)

To właśnie tutaj zapoczątkowano trend projektowy oparty na ciemnej bieli, a ten trend przeniósł się do wczesnych stron internetowych opartych na dokumentach. Pierwsza przeglądarka, WorldWideWeb (pamiętaj, nie wymyślono jeszcze CSS), wyświetlała strony internetowe w ten sposób. Ciekawostka: druga przeglądarka, Line Mode Browser (przeglądarka oparta na terminalu), była zielona w trybie ciemnym. Obecnie strony internetowe i aplikacje internetowe są zwykle projektowane z ciemnym tekstem na jasnym tle, co jest założeniem, które jest też zakodowane na stałe w arkuszach stylów klienta użytkownika, m.in. w Chrome.

Smartfon używany, gdy leży w łóżku
Smartfon używany w łóżku (źródło: Unsplash)

Minęły już czasy CRT. Wykorzystanie i tworzenie treści stało się teraz bardziej popularne w przypadku urządzeń mobilnych wyposażonych w podświetlany ekran LCD lub energooszczędny AMOLED. Mniejsze i bardziej przenośne komputery, tablety i smartfony doprowadziły do powstania nowych wzorców użytkowania. Zadania, takie jak przeglądanie internetu, kodowanie dla rozrywki i granie w zaawansowanych grach, często są wykonywane po godzinach, przy słabym oświetleniu. Ludzie korzystają nawet z urządzeń w łóżkach nocą. Im częściej ludzie korzystają ze swoich urządzeń w ciemności, tym bardziej powszechna staje się pomysł powrotu do korzeni jasności na ciemności.

Dlaczego tryb ciemny

Tryb ciemny ze względów estetycznych

Gdy ktoś zostaje zapytany, dlaczego lubią tryb ciemny lub woli korzystać z trybu ciemnego, najpopularniejsza reakcja brzmi: „jest bardziej czytelny dla oczu”, po czym następuje „elegancki i piękny”. Firma Apple w dokumentacji dla programistów trybu ciemnego wyraźnie pisze: „Wybór jasnego lub ciemnego wyglądu jest dla większości użytkowników estetyczny i może nie mieć związku z oświetleniem otoczenia”.

ZamknijView w systemie Mac OS System 7 z
System 7 CloseView (źródło)

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

Występują też osoby, które potrzebują trybu ciemnego i używają go jako dodatkowego narzędzia ułatwień dostępu, na przykład osoby niedowidzące. Najwcześniejszym narzędziem do ułatwiania dostępu, jakie udało mi się znaleźć, jest funkcja CloseView w Systemie 7 z przełącznikiem Czarno-biały i Biały na czarnym. Mimo że System 7 obsługiwał kolory, domyślny interfejs użytkownika był nadal czarno-biały.

Te implementacje oparte na odwróceniu wykazały słabe punkty po wprowadzeniu koloru. Badania opinii użytkowników przeprowadzone przez Szpiro i in. na temat tego, jak osoby niedowidzące i z komputerami wykazały, że wszystkim ankietowanym użytkownikom nie podobają się odwrócone obrazy, ale wielu z nich woli jasny tekst na ciemnym tle. Apple uwzględnia to ustawienie użytkownika, korzystając z funkcji inteligentnego odwracania, która odwraca kolory na wyświetlaczu z wyjątkiem obrazów, multimediów i niektórych aplikacji, w których stosuje się ciemny styl.

Szczególną postacią wad wzroku jest zespół wzroku komputerowego, nazywany też „cyfrowym zmęczeniem wzroku”. „Połączenie problemów ze wzrokiem i widzeniem wynikających z korzystania z komputerów (w tym komputerów, laptopów i tabletów) oraz innych wyświetlaczy elektronicznych (np. smartfonów i urządzeń elektronicznych do czytania). Zaproponowano, że korzystanie z urządzeń elektronicznych przez nastolatków, zwłaszcza w nocy, zwiększa ryzyko skrócenia czasu snu, wydłużenia czasu zasypiania i braku snu. Zgłoszono też, że ekspozycja na niebieskie światło jest zaangażowana w regulację rytmu okołodobowego i cyklu snu, a nieregularne otoczenie może prowadzić do braku snu, co może wpływać na nastrój i wydajność zadań, jak wynika z badań przeprowadzonych przez Rosenfield. Aby ograniczyć te negatywne skutki, pomóc może redukcja niebieskiego światła przez dostosowanie temperatury kolorów wyświetlacza za pomocą funkcji takich jak Night Shift w iOS i Podświetlenie nocne na Androidzie. Pomóc może też unikanie jasnych i nieregularnych świateł dzięki ciemnym motywom i trybom ciemnym.

Oszczędzanie energii w trybie ciemnym na ekranach AMOLED

I na koniec wiadomo, że tryb ciemny pozwala zaoszczędzić dużo energii na ekranach AMOLED. Studia przypadków Androida, które skupiają się na popularnych aplikacjach Google, np. YouTube, dowodzą, że oszczędność energii może sięgać nawet 60%. Więcej informacji o tych studiach przypadku i oszczędności energii w poszczególnych aplikacjach znajdziesz w filmie poniżej.

Aktywowanie trybu ciemnego w systemie operacyjnym

Skoro już omówiliśmy, dlaczego tryb ciemny jest tak poważny dla wielu użytkowników, zastanówmy się, jak go obsługiwać.

Ustawienia trybu ciemnego w Androidzie Q
Ustawienia ciemnego motywu na Androida Q

Systemy operacyjne, które obsługują tryb ciemny lub motyw ciemny, można zwykle włączyć w ustawieniach. W systemie macOS X znajduje się on w sekcji Ogólne preferencji systemowych, o nazwie Wygląd (zrzut ekranu), a w systemie Windows 10 – w sekcji Kolory o nazwie Wybierz kolor (zrzut ekranu). W przypadku Androida Q znajdziesz go w sekcji Wyświetlacz jako ciemny motyw (zrzut ekranu), a w systemie iOS 13 możesz zmienić Wygląd w sekcji Wyświetlacz i jasność w ustawieniach (zrzut ekranu).

Zapytanie o media prefers-color-scheme

Jeszcze jedna teoria, zanim zacznę. Zapytania o multimedia pozwalają autorom testować i wysyłać zapytania o wartości lub funkcje klienta użytkownika bądź urządzenia wyświetlającego niezależnie od wyświetlanego dokumentu. Są one używane w regule CSS @media do warunkowego stosowania stylów w dokumencie oraz w różnych kontekstach i językach, np. HTML i JavaScript. W ramach zapytań o multimedia na poziomie 5 wprowadziliśmy tzw. funkcje multimedialne związane z preferencjami użytkownika, czyli sposób, w jaki witryny mogą wykrywać preferowany przez użytkownika sposób wyświetlania treści.

Funkcja multimediów prefers-color-scheme służy do wykrywania, czy użytkownik zażądał, aby strona miała motyw kolorystyczny jasny czy ciemny. Działa z tymi wartościami:

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

Obsługuje tryb ciemny

Sprawdzanie, czy przeglądarka obsługuje tryb ciemny

Tryb ciemny jest raportowany na podstawie zapytania o multimedia, więc możesz łatwo sprawdzić, czy obecna przeglądarka obsługuje tryb ciemny, sprawdzając, czy zapytanie o multimedia prefers-color-scheme w ogóle pasuje. Zwróć uwagę, że nie podam żadnej wartości, ale sprawdzę tylko, czy pasuje tylko zapytanie o multimedia.

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

Obecnie usługa prefers-color-scheme jest obsługiwana zarówno na komputerach, jak i urządzeniach mobilnych (o ile jest dostępna) w Chrome i Edge 76, Firefox od wersji 67 oraz Safari od wersji 12.1 na urządzeniach z macOS i od wersji 13 na urządzeniach z iOS. W przypadku wszystkich innych przeglądarek przeczytaj artykuł Czy mogę korzystać z tabel pomocy.

Uzyskiwanie informacji o ustawieniach użytkownika w momencie żądania

Nagłówek wskazówek dla klienta Sec-CH-Prefers-Color-Scheme umożliwia witrynom opcjonalnie uzyskiwanie preferencji schematu kolorów użytkownika w momencie żądania. Pozwala to serwerom na wbudowanie właściwego kodu CSS, a tym samym uniknięcie błysku nieprawidłowego motywu kolorów.

Tryb ciemny w praktyce

Zobaczmy, jak wygląda obsługa trybu ciemnego w praktyce. Tak jak w grze Highlander, w trybie ciemnym może być tylko jeden: ciemny lub jasny, ale nie oba jednocześnie. Dlaczego wspominam o tym? Ponieważ powinien to mieć wpływ na strategię wczytywania. Nie wymuszaj na użytkownikach pobierania kodu CSS z krytycznej ścieżki renderowania, która jest przeznaczona do trybu, którego obecnie nie używają. Aby zoptymalizować szybkość ładowania, podzieliliśmy kod CSS przykładowej aplikacji, która wyświetla w praktyce poniższe rekomendacje, na 3 części. Pozwoli to opóźnić niekrytyczny kod CSS:

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

Strategia wczytywania

Dwie ostatnie, light.css i dark.css, są ładowane warunkowo za pomocą zapytania <link media>. Początkowo nie wszystkie przeglądarki obsługują technologię prefers-color-scheme (wykrywaną za pomocą powyższego wzorca), z którą postępuję dynamicznie, ładując domyślny plik light.css za pomocą warunkowo wstawionego elementu <link rel="stylesheet"> w małym skrypcie w tekście (to wybór dobrowolny, możliwe było też przyciemnienie domyślnego pliku kreacji zastępczej). Aby uniknąć załadowania treści bez stylu, ukrywam treść strony do czasu jej załadowania 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

Wykorzystuję zmienne CSS w maksymalnym zakresie. Dzięki temu ogólne style.css mają charakter ogólny, a wszystkie dostosowania trybu jasnego i ciemnego odbywają się w 2 pozostałych plikach dark.css i light.css. Poniżej znajdziesz fragment rzeczywistych stylów. Powinien on wystarczać do przedstawienia ogólnego założenia. Deklaruję 2 zmienne: -⁠-⁠color i -⁠-⁠background-color, które zasadniczo tworzą motyw bazowy ciemny przy świetle i jasny na ciemno.

/* 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 elemencie style.css używam tych zmiennych w regule body { … }. Zgodnie z definicją w pseudoklasie CSS :root, czyli selektorze, który w kodzie HTML reprezentuje element <html> i jest taki sam jak selektor html, z tą różnicą, że jego specyficzność jest większa, spływają one w dół, co umożliwia deklarowanie globalnych zmiennych CSS.

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

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

W przykładowym kodzie powyżej zapewne udało Ci się zauważyć właściwość color-scheme z wartością light dark oddzieloną spacjami.

Informuje ona przeglądarkę, które motywy kolorystyczne obsługuje moja aplikacja, i aktywuje specjalne wersje arkusza stylów klienta użytkownika, co jest przydatne np. w przypadku, gdy przeglądarka renderuje pola formularza z ciemnym tłem i jasnym tekstem, dostosowuje paski przewijania lub włącza kolor zaznaczenia zależny od motywu. Szczegółowe informacje o obiekcie color-scheme znajdziesz w module dostosowania kolorów CSS – poziom 1.

Cała reszta jest jedynie kwestią określenia zmiennych CSS dla istotnych elementów w witrynie. Semantyczne porządkowanie stylów bardzo przydaje się podczas pracy w trybie ciemnym. Na przykład zamiast funkcji -⁠-⁠highlight-yellow spróbuj wywołać zmienną -⁠-⁠accent-color, ponieważ w trybie ciemnym kolor „żółty” nie musi być żółty i odwrotnie. Poniżej znajdziesz kilka 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

Pełny przykład, który pozwala zastosować opisane wyżej pojęcia w praktyce, znajdziesz poniżej w poniższym fragmencie kodu Glitch. Spróbuj przełączyć tryb ciemny w ustawieniach systemu operacyjnego i zobacz, jak zareaguje strona.

Wpływ wczytywania

Po obejrzeniu tego przykładu dowiesz się, dlaczego wczytuję obiekty dark.css i light.css za pomocą zapytań o multimedia. Przełącz tryb ciemny i załaduj ponownie stronę: określone aktualnie niepasujące arkusze stylów są nadal wczytywane, ale mają najniższy priorytet, tak aby nigdy nie konkurowały z zasobami, które są potrzebne witrynie.

Schemat wczytywania sieci pokazujący, jak w trybie jasnym wczytuje się kod CSS w trybie ciemnym z najniższym priorytetem.
Witryna w trybie jasnym wczytuje kod CSS w trybie ciemnym o najniższym priorytecie.
Schemat wczytywania sieci pokazujący, jak w trybie ciemnym wczytuje się CSS z najniższym priorytetem.
Witryna w trybie ciemnym wczytuje CSS w trybie jasnym z najniższym priorytetem.
Schemat wczytywania sieci pokazujący, jak w domyślnym trybie jasnym wczytuje się kod CSS w trybie ciemnym z najniższym priorytetem.
Witryna w domyślnym trybie jasnym w przeglądarce, która nie obsługuje prefers-color-scheme, wczytuje CSS w trybie ciemnym z najniższym priorytetem.

Reagowanie na zmiany w trybie ciemnym

Tak jak w przypadku każdej innej zmiany zapytań o multimedia, zmiany trybu ciemnego można subskrybować za pomocą JavaScriptu. Za pomocą tej funkcji możesz na przykład dynamicznie zmieniać favikonę strony lub element <meta name="theme-color"> określający kolor paska adresu URL w Chrome. Pełny przykład powyżej pokazuje, jak to działa. Aby zobaczyć, jak zmienia się kolor motywu i favikona, 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'}.`);
});

W Chromium 93 i Safari 15 możesz dostosowywać kolor na podstawie zapytania o multimedia za pomocą atrybutu media elementu koloru motywu meta. Wybrana zostanie pierwsza z nich, która będzie pasować do zapytania. Na przykład możesz mieć jeden kolor do trybu jasnego i ciemny. W czasie tworzenia tekstu nie możesz definiować ich w pliku manifestu. Zobacz problem z w3c/manifest#975 GitHub.

<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 w trybie ciemnym

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

Zmiana schematu kolorów całego systemu operacyjnego może być bardzo irytująca, dlatego w Narzędziach deweloperskich w Chrome możesz teraz emulować schemat kolorów preferowany przez użytkownika w sposób, który ma wpływ tylko na aktualnie widoczną kartę. Otwórz menu poleceń, zacznij pisać Rendering, uruchom polecenie Show Rendering, a następnie zmień opcję Emulate CSS media feature prefers-color-scheme.

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

Tworzę zrzut ekranu aplikacji prefers-color-scheme z Puppeteer

Puppeteer to biblioteka Node.js, która udostępnia ogólny interfejs API 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 ze stron w trybie ciemnym i jasnym. 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

Być może zauważyliście drobnoskę, że nie używam czystej bieli. Zamiast tego wybieram nieco ciemniejszą biel. Coś w rodzaju rgb(250, 250, 250) działa dobrze.

Zmiana kolorów i przyciemnienie zdjęć

Porównując 2 zrzuty ekranu poniżej, zauważysz, że nie tylko główny motyw zmienił się z ciemnego w jasnym na jasny po zmroku, ale też nieco inaczej wygląda baner powitalny. Z moich badań opinii użytkowników wynika, że większość ankietowanych woli mniej żywe i wyraźne zdjęcia w trybie ciemnym. Jest to tzw. ponowna kolorystyka.

Baner główny w trybie ciemnym jest lekko zaciemniony.
Baner powitalny lekko przyciemniony w trybie ciemnym.
Zwykły baner powitalny w trybie jasnym.
Zwykły baner powitalny w trybie jasnym.

Aby zmienić kolorystykę obrazów, użyj filtra CSS. Używam selektora arkusza CSS, który pasuje do wszystkich obrazów, które w adresie URL nie mają tagu .svg. Chodzi o to, że grafikę wektorową (ikony) mogę zmienić w inną kolorystykę niż obrazy (zdjęcia). Więcej informacji na ten temat znajdziesz w następnym akapicie. Zwróć uwagę, jak ponownie używam zmiennej CSS, aby móc później elastycznie zmienić filtr.

Ponowna koloryzacja jest wymagana tylko w trybie ciemnym, czyli gdy dark.css jest aktywny, w zasadzie light.css nie ma odpowiadających im reguł.

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

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

Dostosowywanie intensywności zmiany kolorów w trybie ciemnym za pomocą JavaScriptu

Nie wszyscy są tacy sami i każdy ma inne potrzeby związane z trybem ciemnym. Trzymając się opisanej powyżej metody zmiany kolorów, mogę łatwo zmienić intensywność skali szarości na preferencje użytkownika i zmienić je za pomocą JavaScriptu. Jeśli ustawisz wartość 0%, mogę całkowicie wyłączyć zmianę kolorów. Pamiętaj, że argument document.documentElement zawiera odwołanie do elementu głównego dokumentu, czyli tego samego elementu, do którego mogę się odwołać za pomocą pseudoklasy CSS :root.

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

Odwróć grafikę i ikony wektorowe

W przypadku grafiki wektorowej (która w moim przypadku używam elementów jako ikon, do których odwołują się elementy <img>) używam innej metody rekoloryzacji. Badania wykazały, że użytkownicy nie lubią odwracania zdjęć, ale funkcja ta działa bardzo dobrze z większością ikon. Także w tym przypadku używam zmiennych CSS do określenia wartości odwrócenia w stanie regularnym i w stanie :hover.

W trybie ciemnym ikony są odwrócone.
W trybie ciemnym ikony są odwrócone.
Zwykłe ikony w trybie jasnym.
Zwykłe ikony w trybie jasnym.

Zwróć uwagę, jak ponownie odwracam ikony tylko w dark.css, ale nie w light.css, i jak w 2 przypadkach :hover zwiększa intensywność odwrócenia ikony, aby w zależności od trybu wybranego przez użytkownika była ona nieco ciemniejsza lub nieco jaśniejsza.

/* 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 dla wbudowanych plików SVG

W przypadku wbudowanych obrazów SVG zamiast filtrów odwrócenia możesz użyć słowa kluczowego CSS currentColor, które reprezentuje wartość właściwości color elementu. Dzięki temu możesz 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 używasz currentColor, przyjmuje się ona wartość z odziedziczonej wartości właściwości color. Co więcej, działa to również w przypadku <svg><use href="…"></svg>, więc możesz mieć osobne zasoby, a w kontekście nadal będzie stosowany parametr currentColor. Pamiętaj, że działa to tylko w przypadku plików SVG wbudowanych lub <use href="…">. Nie dotyczy to plików SVG, do których odwołuje się plik src obrazu lub w jakiś sposób za pomocą CSS. Widać to 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 lub odwrotnie można wygładzić dzięki temu, że zarówno właściwości color, jak i background-coloranimowanymi właściwościami CSS. Utworzenie animacji jest proste – wystarczy zadeklarować 2 elementy transition dla 2 właściwości. Przykład poniżej przedstawia ogólną propozycję. Możesz ją zobaczyć 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

Aby wczytywać czynniki związane z wydajnością, zalecam użycie wyłącznie prefers-color-scheme atrybutu media elementów <link> (zamiast wbudowanego w arkusze stylów). W niektórych sytuacjach korzystne może być użycie prefers-color-scheme elementów bezpośrednio w kodzie HTML. Tak wygląda sytuacja w przypadku kierunku artystycznego. W internecie ta koncepcja dotyczy ogólnego wyglądu strony, jej wizualnego oddziaływania, stymulowania nastrojów, kontrastujących cech i atrakcyjności psychologicznej grupy odbiorców.

W trybie ciemnym projektant decyduje o tym, jakie zdjęcie jest najlepsze w danym trybie i czy zmiana koloru obrazów może nie wystarczyć. Jeśli używasz jej z elementem <picture>, wartość <source> wyświetlanego obrazu może być zależna od atrybutu media. W poniższym przykładzie pokazuję półkulę zachodnią dla trybu ciemnego, a półkulę wschodnią w trybie jasnym lub gdy nie wybrano żadnej preferencji. We wszystkich pozostałych przypadkach preferuję półkulę wschodnią. Posłuży to oczywiście wyłącznie do celów poglądowych. Włą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 możliwością rezygnacji

Jak wspomnieliśmy w sekcji o powodach korzystania z trybu ciemnego, większość użytkowników może zdecydować się na tryb ciemny. W efekcie niektórzy użytkownicy mogą chcieć, by interfejs systemu operacyjnego był ciemny, ale nadal wolą widzieć strony internetowe w taki sposób, w jaki są do nich przyzwyczajeni. Dobrym wzorcem jest na początku stosowanie się do sygnału wysyłanego przez przeglądarkę przez prefers-color-scheme, a później opcjonalnie zezwalanie użytkownikom na zastąpienie ustawień na poziomie systemu.

Element niestandardowy <dark-mode-toggle>

Kod możesz oczywiście utworzyć samodzielnie, ale możesz też użyć gotowego elementu niestandardowego (komponentu internetowego) utworzonego specjalnie do tego celu. Ma nazwę <dark-mode-toggle> i dodaje do strony przełącznik (tryb ciemny: włączony/wyłączony) lub przełącznik motywu (jasny/ciemny), który możesz w pełni dostosować. Poniższy przykład pokazuje element w praktyce (a także 🤫 schudłem go też we wszystkich innych przykładach powyżej).

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

W prezentacji poniżej kliknij elementy sterujące trybem ciemnym w prawym górnym rogu. Jeśli zaznaczysz pole wyboru przy trzecim i czwartym elemencie sterującym, sprawdź, jak wybrany tryb jest zapamiętywany nawet po ponownym załadowaniu strony. W ten sposób użytkownicy mogą pozostawić system operacyjny w trybie ciemnym, ale mogą korzystać z witryny w trybie jasnym lub na odwrót.

Podsumowanie

Korzystanie z trybu ciemnego i wspieranie go to świetna zabawa i otwiera nowe możliwości projektowania. W przypadku niektórych użytkowników może być to różnica między brakiem możliwości obsługi strony a spełnianiem oczekiwań użytkowników. Są pewne pułapki i wymagane jest dokładne testowanie, ale tryb ciemny to świetna okazja, aby pokazać, że dbasz o wszystkich użytkowników. Sprawdzone metody wymienione w tym poście oraz elementy pomocnicze, takie jak element niestandardowy <dark-mode-toggle>, pomogą Ci stworzyć niesamowitą atmosferę w trybie ciemnym. Daj mi znać na Twitterze, czy post jest przydatny i czy też warto go ulepszyć. Dziękujemy za uwagę! 🌒

Zasoby dla zapytania o media prefers-color-scheme:

Zasoby dla metatagu color-scheme i właściwości CSS:

Linki do ogólnego trybu ciemnego:

Artykuły badawcze związane z tym postem:

Podziękowania

Zadaniem implementacji jest funkcja mediów prefers-color-scheme, właściwość CSS color-scheme i powiązany metatag 👏 Rune Lillesveen. Rune jest też współredaktorem specyfikacji modułu dostosowania kolorów CSS, poziom 1. Dziękuję Lukaszowi Zbylutowi, Rowanowi Merewood, Chiragowi Desai i Robowi Dodsonowi za dokładne recenzje tego artykułu. Strategia wczytywania jest pomysłem Jake'a Archibalda. Emilio Cobos Álvarez wskaże mi prawidłową metodę wykrywania prefers-color-scheme. Wskazówka z przywołanymi plikami SVG i currentColor pochodzi od Timothy Hatcher. Jestem wdzięczna wielu anonimowym uczestnikom różnych badań opinii, którzy pomogli sformułować zalecenia w tym artykule. Baner powitalny: Nathan Anderson.