Ulepszyliśmy domyślny styl trybu ciemnego za pomocą właściwości CSS schematu kolorów i odpowiedniego metatagu.

Właściwość CSS color-scheme i odpowiadający jej tag meta umożliwiają deweloperom dodanie stron do domyślnych ustawień motywu w arkuszu stylów klienta użytkownika.

Tło

Funkcja mediów prefers-color-scheme dotycząca preferencji użytkownika

Funkcja preferencji użytkownika dotycząca multimediów prefers-color-schemepozwala deweloperom uzyskać pełną kontrolę nad wyglądem stron. Jeśli nie wiesz, czym jest tryb ciemny, przeczytaj mój artykuł prefers-color-scheme: Cześć ciemności, mój stary przyjacielu, w którym zebrałem wszystko, co wiem o tworzeniu niesamowitego ciemnego trybu.

Jednym z elementów układanki, który został tylko krótko wspomniany w artykule, jest właściwość CSS color-scheme i odpowiadający jej tag meta o tej samej nazwie. Oba ułatwiają życie deweloperom, ponieważ pozwalają na zastosowanie do strony domyślnych ustawień motywu w arkuszu stylów klienta użytkownika, takich jak elementy sterujące formularzem, paski przewijania czy kolory systemowe CSS. Jednocześnie funkcja ta zapobiega samodzielnemu stosowaniu przez przeglądarki jakichkolwiek przekształceń.

Obsługa przeglądarek

prefers-color-scheme

Obsługa przeglądarek

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 67.
  • Safari: 12.1.

Źródło

color-scheme

Obsługa przeglądarek

  • Chrome: 81.
  • Edge: 81.
  • Firefox: 96.
  • Safari: 13.

Źródło

Arkusz stylów klienta użytkownika

Zanim przejdę dalej, krótko opiszę, czym jest arkusz stylów klienta użytkownika. W większości przypadków słowo klient użytkownika (UA) możesz rozumieć jako przeglądarka. Szablon UA określa domyślny wygląd i wygląd strony. Jak sugeruje nazwa, arkusz stylów UA zależy od danej wersji UA. Możesz sprawdzić atrybut UA w arkuszu stylów Chrome (i Chromium) i porównać go z atrybutem UA w Firefoksie lub Safari (i WebKit). Zazwyczaj skrypty UA są zgodne w większości kwestii. Na przykład wszystkie mają niebieskie linki, czarny tekst i białe tło, ale są też ważne (a czasem irytujące) różnice, na przykład w stylu elementów sterujących w formularzu.

Przyjrzyj się bliżej schowalni stylów UA w WebKit i sprawdź, jak działa w trybie ciemnym. (w arkuszu stylów przeprowadź pełne wyszukiwanie ciągu „ciemny”). Domyślne ustawienie stylu zmienia się w zależności od tego, czy tryb ciemny jest włączony czy wyłączony. Aby to zilustrować, podajemy przykład reguły CSS, która używa pseudoklasy :matches i zmiennych wewnętrznych WebKit, takich jak -apple-system-control-background, a także wewnętrznej dyrektywy preprocesora WebKit #if defined:

input,
input:matches([type="password"], [type="search"]) {
  -webkit-appearance: textfield;
  #if defined(HAVE_OS_DARK_MODE_SUPPORT) &&
      HAVE_OS_DARK_MODE_SUPPORT
    color: text;
    background-color: -apple-system-control-background;
  #else
    background-color: white;
  #endif
  /* snip */
}

W przypadku właściwości color i background-color zobaczysz niestandardowe wartości. Ani text, ani -apple-system-control-background nie są prawidłowymi kolorami CSS. Są to semantyczne kolory wewnętrzne WebKit.

Okazuje się, że CSS ma ustandaryzowane semantyczne kolory systemu. Są one określone w CSS Color Module Level 4. Na przykład: Canvas (nie mylić z tagiem <canvas>) to tło treści aplikacji lub dokumentów, a CanvasText to tekst w treści aplikacji lub dokumentach. Te 2 elementy są ze sobą powiązane i nie należy ich używać osobno.

Szablony stylów UA mogą używać własnych zastrzeżonych kolorów lub kolorów ze standaryzowanego systemu semantycznego, aby określić, jak domyślnie powinny być renderowane elementy HTML. Jeśli system operacyjny jest ustawiony na tryb ciemny lub używa ciemnego motywu, element CanvasText (lub text) będzie warunkowo biały, a element Canvas (lub -apple-system-control-background) będzie czarny. W efekcie spersonalizowana szata UA przypisuje ten kod CSS tylko raz i obsługuje zarówno tryb jasny, jak i ciemny.

/**
  Not actual UA stylesheet code.
  For illustrative purposes only.
*/
body {
  color: CanvasText;
  background-color: Canvas
}

Właściwość CSS color-scheme

Specyfikacja CSS Color Adjustment Module Level 1 wprowadza model i sterowanie automatycznym dostosowywaniem kolorów przez agenta użytkownika w celu obsługi preferencji użytkownika, takich jak tryb ciemny, korekta kontrastu czy konkretne schematy kolorów.

Zdefiniowana w nim właściwość color-scheme pozwala elementowi wskazać, w których schematach kolorów może być renderowany. Te wartości są negocjowane z uwzględnieniem preferencji użytkownika, co powoduje wybraną kolorystykę, która wpływa na elementy interfejsu użytkownika (UI), takie jak domyślne kolory elementów sterujących formularzem i pasków przewijania, a także używane wartości kolorów systemu CSS. Obecnie obsługiwane są te wartości:

  • normal Wskazuje, że element nie ma pojęcia o schematach kolorów, dlatego powinien zostać wyrenderowany z użyciem domyślnego schematu kolorów przeglądarki.

  • [ light | dark ]+ Wskazuje, że element zna wymienione schematy kolorów i może je obsługiwać, a także wyraża preferencje dotyczące ich kolejności.

Na tej liście light oznacza jasną paletę kolorów z jasnymi kolorami tła i ciemnymi kolorami pierwszego planu, a dark odwrotnie – ciemnymi kolorami tła i jasnymi kolorami pierwszego planu.

W przypadku wszystkich elementów renderowanie za pomocą schematu kolorów powinno powodować, że kolory używane we wszystkich elementach interfejsu udostępnianych przez przeglądarkę będą pasować do zamierzonego schematu kolorów. Przykłady to suwaki, podkreślenia w ramach sprawdzania pisowni, elementy sterujące formularzy itp.

W przypadku elementu :root renderowanie za pomocą schematu kolorów musi dodatkowo wpływać na kolor powierzchni płótna (czyli globalny kolor tła), początkową wartość właściwości color i używane wartości kolorów systemowych. Powinna też wpływać na suwaki przewijania w obszarze widoku.

/*
  The page supports both dark and light color schemes,
  and the page author prefers dark.
*/
:root {
  color-scheme: dark light;
}

metatag color-scheme,

Honorowanie właściwości CSS color-scheme wymaga najpierw pobrania pliku CSS (jeśli jest on wywoływany za pomocą <link rel="stylesheet">) i przeanalizowania go. Aby ułatwić przeglądarkom renderowanie tła strony z pożądaną kolorystyką natychmiast, możesz podać wartość color-scheme w elemencie <meta name="color-scheme">.

<!--
  The page supports both dark and light color schemes,
  and the page author prefers dark.
-->
<meta name="color-scheme" content="dark light">

Łączenie wymiarów color-schemeprefers-color-scheme

Zarówno metatag, jak i właściwość CSS (jeśli zostanie zastosowana do elementu :root) działają w ten sam sposób, dlatego zawsze zalecam określenie schematu kolorów za pomocą metatagu, aby przeglądarka mogła szybciej dostosować się do preferowanego schematu.

W przypadku stron z bezwzględnym tłem nie są wymagane żadne dodatkowe reguły CSS, ale ogólnie zawsze należy łączyć color-schemeprefers-color-scheme. Na przykład zastrzeżony kolor -webkit-link w języku CSS WebKit, używany przez WebKit i Chrome do klasycznego niebieskiego koloru linku rgb(0,0,238), ma niewystarczający współczynnik kontrastu 2,23:1 na czarnym tle i nie spełnia zarówno wymagań WCAG AA, jak i WCAG AAA.

Aby rozwiązać ten problem, otworzyłem zgłoszenia błędów w Chrome, WebKitFirefox, a także problem meta w standardzie HTML.

Interakcja z: prefers-color-scheme

Na początku może wydawać się, że współdziałanie właściwości color-scheme w kodzie CSS i odpowiedniego metatagu z funkcją mediów prefers-color-scheme dotyczącą preferencji użytkownika może być mylące. W fakcie świetnie się razem dopełniają. Najważniejsze jest to, że color-schemeokreśla wyłącznie domyślny wygląd, podczas gdy prefers-color-schemeokreśla wygląd stylizowany. Aby to wyjaśnić, weź pod uwagę tę stronę:

<head>
  <meta name="color-scheme" content="dark light">
  <style>
    fieldset {
      background-color: gainsboro;
    }
    @media (prefers-color-scheme: dark) {
      fieldset {
        background-color: darkslategray;
      }
    }
  </style>
</head>
<body>
  <p>
    Lorem ipsum dolor sit amet, legere ancillae ne vis.
  </p>
  <form>
    <fieldset>
      <legend>Lorem ipsum</legend>
      <button type="button">Lorem ipsum</button>
    </fieldset>
  </form>
</body>

Wbudowany kod CSS na stronie ustawia wartość background-color elementu <fieldset> na gainsboro w ogólnym przypadku, a na darkslategray, jeśli użytkownik preferuje schemat kolorów dark zgodnie z funkcją mediów prefers-color-scheme preferencji użytkownika.

Za pomocą elementu <meta name="color-scheme" content="dark light"> strona informuje przeglądarkę, że obsługuje ciemny i jasny motyw, przy czym preferuje ciemny.

W zależności od tego, czy system operacyjny jest w trybie ciemnym czy jasnym, cała strona będzie wyświetlana w wersji jasnej na ciemnym tle lub odwrotnie, w zależności od arkusza stylów użytkownika. Aby zmienić tekst akapitu lub kolor tła strony, nie trzeba używać dodatkowego kodu CSS dostarczonego przez programistę.

Zwróć uwagę, jak element <fieldset> zmienia się w zależności od tego, czy tryb ciemny jest włączony, zgodnie z regułami wbudowanej w stronę spersonalizowanej przez dewelopera arkusz stylów.background-color Może to być gainsboro lub darkslategray.

Strona w trybie jasnym.
Tryb jasny: style określone przez dewelopera i klienta użytkownika. Tekst jest czarny, a tło białe zgodnie ze stylem przeglądarki. Wartość atrybutu background-color elementu <fieldset> to gainsboro, zgodnie z wbudowanym stylem dewelopera.
Strona w trybie ciemnym.
Tryb ciemny: style określone przez dewelopera i klienta użytkownika. Tekst jest biały, a tło czarne zgodnie ze stylem klienta użytkownika. Wartość atrybutu background-color elementu <fieldset> to darkslategray, zgodnie z wbudowanym stylem dewelopera.

Wygląd elementu <button> jest kontrolowany przez arkusz stylów klienta użytkownika. W przypadku elementu color ustawiono kolor ButtonText, a elementy background-color i cztery elementy border-color mają kolor systemowy ButtonFace.

Strona w jasnym trybie, która używa właściwości ButtonFace.
Tryb jasny: background-color i różne border-color są ustawione na kolor systemu ButtonFace.

Zwróć uwagę, jak zmienia się wartość border-color elementu <button>. Obliczona wartość atrybutów border-top-colorborder-bottom-color zmienia się z rgba(0, 0, 0, 0.847) (czarnego) na rgba(255, 255, 255, 0.847) (białego), ponieważ klient użytkownika aktualizuje dynamicznie atrybuty ButtonFace na podstawie schematu kolorów. To samo dotyczy elementu <button>, którego właściwość color ma ustawiony odpowiedni kolor systemu ButtonText.

Wyświetlanie zgodności obliczonych wartości kolorów z wartościami w przycisku.
Tryb jasny: obliczone wartości atrybutów border-top-colorborder-bottom-color, które w arkuszu stylów klienta użytkownika mają wartość ButtonFace, mają teraz wartość rgba(0, 0, 0, 0.847).
Pokazuje, że obliczone wartości kolorów nadal pasują do ButtonFace w trybie ciemnym.
Tryb ciemny: obliczone wartości atrybutów border-top-colorborder-bottom-color, które w arkuszu stylów klienta użytkownika mają wartość ButtonFace są teraz rgba(255, 255, 255, 0.847).

Prezentacja

Efekty color-scheme zastosowane do dużej liczby elementów HTML możesz zobaczyć w demonstracji na Glitch. Wersja demonstracyjna celowo pokazuje naruszenie standardów WCAG AA i WCAG AAA z kolorami linków wymienionymi w powyższym ostrzeżeniu.

Demonstracja w trybie jasnym.
Tryb demo toggled to color-scheme: light.
Demonstracja w trybie ciemnym.
demo toggled to color-scheme: dark. Zwróć uwagę na kolory linków wskazujące na naruszenie standardów WCAG AA i WCAG AAA.

Podziękowania

Właściwość CSS color-scheme i odpowiadający jej tag meta zostały zaimplementowane przez Rune Lillesveen. Rune jest też współredaktorem specyfikacji modułu regulacji kolorów CSS na poziomie 1. Baner powitalny autorstwa Philippe Leone z Unsplash.