Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Темизация интерфейса: CSS-переменные

Темизация интерфейса: переключение тем на CSS-переменных

Переключение светлой и тёмной темы: наборы CSS-переменных, выбор по настройке системы и области действия без правки компонентов.

Прямой ответ

Тема задаётся набором значений CSS‑переменных, поэтому переключение выполняется подстановкой набора без изменения компонентов.

Что задаётся Как применяется
Набор переменных Определяет значения темы
Выбор темы По настройке системы либо действию
Область действия Часть интерфейса использует свой набор
Переключение Подстановка набора без правки компонента
:root { --bg: #ffffff; --text: #1a1a1a; }
@media (prefers-color-scheme: dark) {
  :root { --bg: #1a1a1a; --text: #f5f5f5; }
}

Компонент ссылается на переменную, поэтому смена темы не требует правки компонента. О значениях — в статье про дизайн‑токены.

Наборы значений и выбор темы

Тема определяется набором значений, поэтому выбор темы выполняется подстановкой набора для области.

Светлый и тёмный набор. Каждой теме соответствует набор значений, поэтому переключение выполняется заменой набора.

Выбор по настройке системы. Набор применяется по настройке устройства, поэтому интерфейс соответствует ожиданию пользователя без действия.

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

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

Отдельный аспект — сохранение выбора. Выбранная пользователем тема применяется при следующем посещении, поэтому набор подставляется до отображения содержимого, и смена значений после отображения не видна.

Область действия и частичная тема

Переменные действуют для области, поэтому часть интерфейса использует набор, отличающийся от остального.

Область страницы. Набор задаётся для страницы, поэтому все элементы внутри используют значения набора.

Область части интерфейса. Набор задаётся для отдельной области, поэтому область отображается иначе, чем остальная страница.

Наследование значений. Область без собственного набора использует значения родительской области, поэтому переопределение требуется только для отличающейся части.

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

Контрастность значений и проверка темы

Каждый набор значений проверяется на соотношение цвета текста и фона, поэтому тема соответствует требованию доступности.

Соотношение в каждом наборе. Значения светлого и тёмного набора проверяются отдельно, поэтому соответствие требованию подтверждается для каждой темы.

Проверка после переключения. Переключение темы не изменяет соотношение автоматически, поэтому значение, соответствующее в одном наборе, может не соответствовать в другом.

Состояния элемента. Значения для состояний проверяются в каждой теме, поэтому состояние, различимое в светлой теме, остаётся различимым в тёмной.

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

О требованиях к соотношению — в статье про контрастность цветов; о структуре системы — в статье про дизайн‑систему.

Практика: настройка переключения тем

1. Задавайте значения через переменные в каждом наборе. Переключение выполняется подстановкой набора.

2. Не задавайте значения вне набора. Значение вне набора не изменяется при переключении темы.

3. Применяйте выбор по настройке системы. Интерфейс соответствует ожиданию пользователя без действия.

4. Сохраняйте выбор пользователя между посещениями. Выбранная тема применяется при следующем посещении.

5. Подставляйте набор до отображения содержимого. Смена значений после отображения не видна пользователю.

6. Задавайте набор для области, а не для каждого элемента. Дублирование значений не требуется.

7. Проверяйте соотношение цвета в каждом наборе. Соответствие требованию подтверждается для каждой темы.

Рекомендации:

  1. Не переопределяйте переменные для каждого элемента. Изменение набора требует правки всех мест переопределения.
  2. Проверяйте значения состояний в каждой теме. Состояние, различимое в одном наборе, может не различаться в другом.
  3. Не полагайтесь на соответствие в одной теме. Проверка выполняется для каждого набора значений отдельно.
  4. Фиксируйте состав наборов при добавлении темы. Новая тема требует полного набора значений.
  5. Пересматриваем значения при изменении токенов. Обновление токена применяется ко всем наборам темы.

Практический сценарий: тёмная тема отображала светлые значения

Контекст: после переключения на тёмную тему часть элементов сохраняла светлый фон, поэтому текст становился неразличимым.

  1. Диагностика. Проверка показала, что часть компонентов задавала значение фона литерально, а не через переменную. Подстановка тёмного набора применилась к компонентам со ссылкой на переменную, поэтому элементы с литералом сохранили светлое значение.
  2. Причина. Компоненты создавались до введения наборов тем, поэтому значения задавались непосредственно, и перевод на переменные не был завершён.
  3. Действия. (а) Составили перечень компонентов с литеральными значениями цвета, чтобы объём правки был известен; (б) заменили литералы на ссылки на переменные, чтобы значение задавалось набором темы; (в) задали полный набор значений для тёмной темы, чтобы ни одна переменная не осталась без значения; (г) проверили соотношение цвета текста и фона в каждом наборе, чтобы различимость подтверждалась для обеих тем; (д) добавили проверку на отсутствие литеральных значений цвета при сборке, чтобы новый компонент не повторял ошибку.
  4. Результат. Переключение темы применяется ко всем элементам, поскольку значения задаются набором переменных, а различимость подтверждена для обеих тем.

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

FAQ

Как переключается тема на CSS-переменных? Подстановкой другого набора значений для области. Компонент не изменяется, поскольку ссылается на переменную.

Почему часть элементов не меняет цвет при переключении? Элемент задаёт значение литерально, а не через переменную. Подстановка набора не затрагивает литерал.

Нужно ли проверять контрастность в каждой теме? Да. Соответствие требованию в светлом наборе не гарантирует соответствия в тёмном.

Как задать тему для части интерфейса? Набором переменных для области. Область без собственного набора использует значения родительской области.

Источники: W3C CSS Variables, W3C Media Queries prefers-color-scheme, MDN CSS cascading variables — ссылки в шапке.