Улучшен стиль по умолчанию в темном режиме с использованием свойства CSS цветовой схемы и соответствующего метатега.

Свойство CSS color-scheme и соответствующий метатег позволяют разработчикам выбирать для своих страниц специфичные для темы значения по умолчанию из таблицы стилей пользовательского агента.

Фон

Функция медиа-предпочтений пользователя prefers-color-scheme

Функция пользовательской настройки prefers-color-scheme предоставляет разработчикам полный контроль над внешним видом своих страниц. Если вы с ней не знакомы, прочтите мою статью prefers-color-scheme : Привет, тьма, мой старый друг» , где я изложил всё, что знаю о создании потрясающего тёмного режима.

Один из элементов пазла, о котором в статье упоминалось лишь вскользь, — это CSS color-scheme » и соответствующий одноимённый метатег. Они упрощают жизнь разработчика, позволяя настроить для страницы параметры по умолчанию, специфичные для темы, из таблицы стилей пользовательского агента, такие как элементы управления формами, полосы прокрутки и системные цвета CSS. В то же время эта функция не позволяет браузерам самостоятельно применять какие-либо преобразования.

Поддержка браузеров

prefers-color-scheme

Browser Support

  • Хром: 76.
  • Край: 79.
  • Firefox: 67.
  • Сафари: 12.1.

Source

color-scheme

Browser Support

  • Хром: 81.
  • Край: 81.
  • Firefox: 96.
  • Сафари: 13.

Source

Таблица стилей пользовательского агента

Прежде чем продолжить, позвольте мне вкратце описать, что такое таблица стилей пользовательского агента. В большинстве случаев вы можете воспринимать словосочетание «пользовательский агент» (UA) как модное название браузера . Таблица стилей UA определяет внешний вид страницы по умолчанию. Как следует из названия, таблица стилей UA зависит от рассматриваемого UA. Вы можете взглянуть на таблицу стилей UA Chrome (и Chromium) и сравнить её с таблицей стилей Firefox или Safari (и WebKit). Как правило, таблицы стилей UA совпадают по большинству параметров. Например, все они делают ссылки синими, общий текст — чёрным, а цвет фона — белым, но есть и важные (а иногда и раздражающие) различия, например, в том, как они оформляют элементы управления формами.

Подробно изучите таблицу стилей UA WebKit и её работу с тёмным режимом. (Выполните поиск по слову «тёмный» в таблице стилей.) Значение по умолчанию, заданное таблицей стилей, меняется в зависимости от того, включён ли тёмный режим. Для иллюстрации приведём одно из таких правил CSS, использующее псевдокласс :matches и внутренние переменные WebKit, такие как -apple-system-control-background , а также директиву препроцессора 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 */
}

Вы заметите некоторые нестандартные значения свойств color и background-color указанных выше. Ни text , ни -apple-system-control-background не являются допустимыми цветами CSS. Это внутренние семантические цвета WebKit.

Оказывается, в CSS есть стандартизированная семантическая система цветов. Они определены в CSS Color Module Level 4. Например, Canvas (не путать с тегом <canvas> ) предназначен для фона содержимого приложений или документов, а CanvasText — для текста в содержимом приложений или документах. Эти два элемента используются вместе и не должны использоваться изолированно.

Таблицы стилей UA могут использовать как собственные, так и стандартизированные семантические системные цвета для определения того, как HTML-элементы должны отображаться по умолчанию. Если операционная система настроена на тёмный режим или использует тёмную тему, CanvasText (или text ) будет условно установлен белым, а Canvas (или -apple-system-control-background ) — чёрным. В этом случае таблица стилей UA назначает следующий CSS-код только один раз и охватывает как светлый, так и тёмный режимы.

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

Свойство CSS color-scheme

Спецификация модуля регулировки цвета CSS уровня 1 представляет модель и управляет автоматической регулировкой цвета пользовательским агентом с целью обработки пользовательских предпочтений, таких как темный режим, регулировка контрастности или определенные желаемые цветовые схемы.

Свойство color-scheme , определённое в нём, позволяет элементу указать, какие цветовые схемы ему комфортны для отображения. Эти значения согласуются с предпочтениями пользователя, что приводит к выбору цветовой схемы, которая влияет на такие элементы пользовательского интерфейса (UI), как цвета по умолчанию для элементов управления формами и полос прокрутки, а также на используемые значения системных цветов CSS. В настоящее время поддерживаются следующие значения:

  • normal Указывает, что элемент вообще не знает о цветовых схемах, поэтому элемент должен отображаться с использованием цветовой схемы браузера по умолчанию.

  • [ light | dark ]+ Указывает, что элемент распознает и может обрабатывать перечисленные цветовые схемы, а также выражает упорядоченные предпочтения между ними.

В этом списке light представляет светлую цветовую схему со светлыми цветами фона и темными цветами переднего плана, тогда как dark представляет противоположное — с темными цветами фона и светлыми цветами переднего плана.

Для всех элементов рендеринг с цветовой схемой должен обеспечивать соответствие цветов, используемых во всех элементах пользовательского интерфейса браузера, заданной цветовой схемой. Примерами могут служить полосы прокрутки, подчёркивания при проверке орфографии, элементы управления формами и т. д.

В элементе :root рендеринг с цветовой схемой дополнительно должен влиять на цвет поверхности холста (то есть глобальный цвет фона), начальное значение свойства color и используемые значения системных цветов, а также должен влиять на полосы прокрутки области просмотра.

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

Метатег color-scheme

Для использования свойства CSS color-scheme необходимо сначала загрузить CSS-код (если на него ссылаются через <link rel="stylesheet"> ) и проанализировать его. Чтобы помочь пользовательским агентам мгновенно отрисовывать фон страницы с нужной цветовой схемой, значение color-scheme можно также указать в элементе <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">

Объединение color-scheme и prefers-color-scheme

Поскольку и метатег, и свойство CSS (если оно применено к элементу :root ) в конечном итоге приводят к одному и тому же поведению, я всегда рекомендую указывать цветовую схему через метатег, чтобы браузер мог быстрее адаптироваться к предпочтительной схеме.

Хотя для страниц с абсолютным базовым уровнем дополнительные правила CSS не требуются, в общем случае всегда следует сочетать color-scheme с prefers-color-scheme . Например, фирменный CSS-цвет WebKit -webkit-link , используемый WebKit и Chrome для классического синего цвета ссылки rgb(0,0,238) , имеет недостаточный коэффициент контрастности 2,23:1 на чёрном фоне и не соответствует требованиям как WCAG AA, так и WCAG AAA .

Я раскрыл ошибки для Chrome , WebKit и Firefox , а также метапроблему в стандарте HTML, чтобы исправить это.

Взаимодействие с prefers-color-scheme

Взаимодействие CSS-свойства color-scheme и соответствующего метатега с пользовательской медиа-функцией prefers-color-scheme может на первый взгляд показаться запутанным. На самом деле, они отлично сочетаются друг с другом. Важно понимать, что color-scheme определяет исключительно внешний вид по умолчанию, тогда как prefers-color-scheme — внешний вид с возможностью стилизации. Чтобы прояснить это, представим следующую страницу:

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

Встроенный код CSS на странице устанавливает для элемента <fieldset> background-color gainsboro в общем случае и darkslategray , если пользователь предпочитает dark цветовую схему в соответствии с пользовательской настройкой медиафункции prefers-color-scheme .

С помощью элемента <meta name="color-scheme" content="dark light"> страница сообщает браузеру, что она поддерживает темную и светлую тему, с предпочтением темной темы.

В зависимости от того, настроена ли операционная система на тёмный или светлый режим, вся страница отображается светлым фоном на тёмном фоне или наоборот, в соответствии со стилями пользовательского агента. Для изменения текста абзаца или цвета фона страницы не требуется дополнительных CSS-стилей разработчика.

Обратите внимание, как background-color элемента <fieldset> меняется в зависимости от того, включён ли тёмный режим, следуя правилам встроенной таблицы стилей, предоставленной разработчиком на странице. Он может быть gainsboro или darkslategray .

Страница в облегченном режиме.
Светлый режим: стили, заданные разработчиком и пользовательским агентом. Текст чёрный, а фон белый, согласно таблице стилей пользовательского агента. background-color элемента <fieldset>gainsboro , согласно встроенной таблице стилей разработчика.
Страница в тёмном режиме.
Тёмный режим: стили, заданные разработчиком и пользовательским агентом. Текст белый, а фон чёрный, согласно таблице стилей пользовательского агента. background-color элемента <fieldset>darkslategray согласно встроенной таблице стилей разработчика.

Внешний вид элемента <button> определяется таблицей стилей пользовательского агента. Его color задаётся системным цветом ButtonText , а background-color и четыре border-color — системным цветом ButtonFace .

Страница в облегченном режиме, использующая свойство ButtonFace.
Светлый режим: background-color и различные border-color задаются в соответствии с системным цветом ButtonFace .

Теперь обратите внимание, как меняется border-color элемента <button> . Вычисленные значения border-top-color и border-bottom-color меняются с rgba(0, 0, 0, 0.847) (черноватый) на rgba(255, 255, 255, 0.847) (беловатый), поскольку пользовательский агент динамически обновляет ButtonFace в соответствии с цветовой схемой. То же самое относится и к color элемента <button> , который устанавливается в соответствии с системным цветом ButtonText .

Показывает, что вычисленные значения цвета соответствуют ButtonFace.
Режим Light: вычисляемые значения border-top-color и border-bottom-color , заданные для ButtonFace в таблице стилей пользовательского агента, теперь равны rgba(0, 0, 0, 0.847) .
Показывает, что вычисленные значения цвета по-прежнему соответствуют ButtonFace в темном режиме.
Темный режим: вычисляемые значения border-top-color и border-bottom-color , заданные для ButtonFace в таблице стилей пользовательского агента, теперь равны rgba(255, 255, 255, 0.847) .

Демо

Эффект color-scheme , применённой к большому количеству HTML-элементов, можно увидеть в демо-ролике на Glitch . В демо-ролике намеренно показано нарушение WCAG AA и WCAG AAA с помощью цветов ссылок, упомянутых в предупреждении выше.

Демонстрация в облегченном режиме.
Демонстрация переключилась на color-scheme: light .
Демонстрация в тёмном режиме.
Демонстрация переключилась на color-scheme: dark . Обратите внимание на нарушение WCAG AA и WCAG AAA в цветах ссылок.

Благодарности

CSS color-scheme и соответствующий метатег были реализованы Руне Лиллесвеном . Руне также является соредактором спецификации CSS Color Adjustment Module Level 1. Изображение Филиппа Леоне на Unsplash .