
CSS-переменные позволяют менять цветовую схему сайта без копирования стилей: задайте семантические токены, определите значения для каждой темы и переключайте их атрибутом или классом на корневом элементе. Системную тему учитывайте через медиазапрос, а выбор пользователя - отдельным приоритетным правилом. Перед выпуском проверьте контраст, каскад, сохранение настроек и работу без JavaScript.
Опорные решения для безопасной смены темы
- Называйте переменные по назначению: например,
--color-text, а не по оттенку вроде--dark-gray. - Храните общие стили компонентов отдельно от значений цветовых токенов.
- Для ручного выбора используйте единый атрибут или класс на корневом элементе документа.
- Не считайте системную настройку и выбор пользователя одним состоянием: задайте понятный порядок приоритетов.
- Проверьте контраст, фокус клавиатуры и резервные значения до публикации.
Как разложить цвета и другие параметры по семантическим CSS-переменным
Подход подходит сайту с несколькими цветовыми схемами, общими компонентами и единым набором стилей. Он также удобен, когда интерфейс расширяется: разработчику достаточно переопределить токены, не переписывая правила для кнопок, карточек и форм.
Не усложняйте проект темами, если у сайта одна неизменная схема и нет планов добавлять другие варианты. В таком случае достаточно обычных CSS-значений. При проектировании новой платформы или такой задаче, как разработка сайта с несколькими темами, предусмотрите токены заранее. Это особенно полезно, если работа входит в создание сайта под ключ или услуги веб-разработки, где важно согласовать дизайн и реализацию.
Разделяйте переменные на семантические роли: текст, фон страницы, поверхность карточки, граница, акцент, состояние ошибки. При необходимости заведите отдельный слой токенов для компонентов, но не привязывайте всю систему к конкретным названиям цветов.
:root {
--color-text: #202124;
--color-background: #ffffff;
--color-surface: #f3f4f6;
--color-border: #c7c9cc;
--color-accent: #174ea6;
}
.card {
color: var(--color-text);
background: var(--color-surface);
border: 1px solid var(--color-border);
}
Где хранить базовые значения и как переопределять их для каждой темы
Базовые значения удобно объявлять в :root: они доступны всему документу и служат резервной схемой. Значения альтернативной темы задавайте через атрибут, например data-theme, на корневом элементе. Селектор с атрибутом переопределит только токены, поэтому правила компонентов останутся общими.
Для работы понадобятся доступ к CSS и разметке корневого элемента, перечень используемых цветов и возможность проверить интерфейс в браузере. Если проект уже использует дизайн-токены или сборку CSS, включите новые переменные в существующий процесс, а не создавайте параллельный набор.
:root {
color-scheme: light;
--color-text: #202124;
--color-background: #ffffff;
--color-surface: #f3f4f6;
}
:root[data-theme="dark"] {
color-scheme: dark;
--color-text: #f1f3f4;
--color-background: #17191c;
--color-surface: #24272b;
}
Свойство color-scheme сообщает браузеру о схеме интерфейса и помогает согласовать с ней встроенные элементы управления. Оно не заменяет настройку цветов ваших компонентов.
Как переключать темы через атрибуты и классы без дублирования стилей
Перед реализацией учтите риски:
- Неверно выбранный контраст может сделать текст или элементы управления плохо различимыми.
- Конфликт селекторов и порядок правил способны перекрыть значения темы.
- Сохранённое значение может быть устаревшим или не соответствовать поддерживаемым темам.
- Если скрипт не загрузился, пользовательский переключатель не сработает; задайте рабочую схему по умолчанию.
- Определите токены. Перечислите цвета и другие параметры, которые меняются между схемами. Подключите их к стилям компонентов через
var(). - Назначьте значения по умолчанию. Объявите базовые токены в
:rootи укажите резервное значение там, где отсутствие переменной может нарушить отображение. Например, используйтеcolor: var(--color-text, #202124). - Опишите альтернативную тему. Переопределите тот же набор токенов селектором
:root[data-theme="dark"]или классом на корневом элементе. Не дублируйте стили всех компонентов. - Добавьте управление темой. Переключатель должен менять значение атрибута на корневом элементе, например с
lightнаdark. Обновляйте доступное имя или состояние переключателя, чтобы было понятно, какая тема выбрана. - Сохраните пользовательский выбор. Если проекту нужна постоянная настройка, храните только допустимое значение и проверяйте его при чтении. Не используйте сохранённое значение как произвольный фрагмент CSS или HTML.
- Проверьте начальную отрисовку. Убедитесь, что базовая тема видна до выполнения скрипта и что переключение не оставляет часть интерфейса в прежней схеме.
Так реализуется схема, по которой можно понять, как сделать переключение тем на сайте CSS: CSS отвечает за внешний вид, а скрипт при необходимости меняет состояние. Само переопределение переменных работает и без JavaScript, если атрибут темы задан в HTML.
Как учитывать системные предпочтения и сохранять выбор пользователя
Медиазапрос prefers-color-scheme позволяет применить схему, выбранную в настройках устройства. Если пользователь вручную выбрал тему, сохранённое решение обычно должно иметь приоритет над автоматическим. Заранее определите это правило и применяйте его одинаково при первой загрузке и последующих посещениях.
Проверьте результат по списку:
- Без сохранённого выбора сайт использует системную схему или явно выбранную базовую тему.
- Ручное переключение сразу меняет тему у всех компонентов.
- После перезагрузки сохраняется только поддерживаемое значение темы.
- Изменение системной настройки влияет на сайт, если пользователь не задавал собственный выбор.
- Пользователь может вернуться к автоматическому режиму, если он предусмотрен интерфейсом.
- При отключённом или ошибочном JavaScript остаются читаемый контент и базовые стили.
- Состояние переключателя соответствует текущей теме и доступно при навигации с клавиатуры.
Какие контрастные ошибки и сбои каскада проверить до выпуска
- Не переопределён цвет текста или фон вложенного элемента, поэтому он остаётся из другой темы.
- Для поля, кнопки или ссылки задан цвет напрямую вместо семантической переменной.
- Один токен используется для текста и декоративной границы, хотя в темах им нужны разные значения.
- Фокус клавиатуры теряется на фоне или отличается от состояния наведения.
- Состояния ошибки, успеха и отключённого элемента не различимы без опоры только на цвет.
- Селектор темы проигрывает более специфичному правилу или переопределяется стилями компонента.
- В значении переменной есть синтаксическая ошибка, из-за которой свойство не получает ожидаемый цвет.
- Изображения, SVG или встроенные виджеты не рассчитаны на обе схемы и визуально выбиваются из интерфейса.
Проверяйте текст, интерактивные элементы и фокус отдельно в каждой теме. Не полагайтесь только на визуальное впечатление: используйте проверку контрастности и убедитесь, что важные состояния дополнительно обозначены текстом, формой или значком.
Как тестировать темы на компонентах, в разных браузерах и без JavaScript
- Проверка всей страницы. Переключите схему на корневом элементе и пройдите основные сценарии: навигацию, формы, сообщения об ошибках и модальные окна.
- Проверка отдельных компонентов. Просмотрите карточки, кнопки и поля в изоляции, чтобы найти цвета, заданные напрямую.
- Проверка системного режима. Измените предпочтение светлой или тёмной схемы в настройках устройства и проверьте поведение сайта без ручного выбора.
- Проверка без JavaScript. Отключите скрипты или проверьте документ с базовой темой. Контент должен оставаться читаемым, а стили - применяться.
Если переключение не требуется, ограничьтесь системным медиазапросом. Если нужен выбор пользователя, используйте атрибут или класс и небольшую логику управления. Для сайтов с дизайн-системой храните токены централизованно; для изолированного компонента допустимы локальные переменные, если они не дублируют общие роли.
Практические ситуации при настройке цветовых схем сайта
Где лучше объявлять переменные темы?
Общие значения задавайте в :root, а альтернативные - селектором с атрибутом или классом на корневом элементе. Локальные переменные используйте для параметров, относящихся только к отдельному компоненту.
Можно ли переключать тему без JavaScript?
Да, если атрибут или класс темы уже присутствует в HTML либо схема определяется медиазапросом. Для интерактивного переключателя и сохранения выбора обычно нужен JavaScript.
Что должно быть приоритетнее: системная настройка или ручной выбор?
Задайте явное правило: например, автоматически следовать системе, пока пользователь не выбрал тему вручную. Сохранённое значение проверяйте на принадлежность к списку поддерживаемых тем.
Нужно ли задавать резервные значения в var()?
Это полезно, если переменная может отсутствовать из-за ошибки, неполной загрузки стилей или применения компонента вне обычного контекста. Резервное значение должно сохранять читаемость и не подменять проверку корректности темы.
Почему часть компонентов не меняет цвет?
Чаще всего цвет задан напрямую, переменная не подключена к компоненту или правило темы проигрывает по специфичности. Найдите вычисленное значение свойства в инструментах разработчика и проверьте порядок CSS-правил.
Как проверить доступность тёмной схемы?
Проверьте различимость текста, границ, фокуса и состояний элементов в каждой теме. Не передавайте смысл только цветом: добавьте подписи, значки или другие визуальные признаки.
Автор: Наталья Орлова.