Создание темного и светлого режима сайта с помощью свойства color-scheme и light-dark()

Тёмная сторона силы без костылей: осваиваем light-dark() и color-scheme

Слушай, помнишь тот «чудный» момент, когда на середине проекта заказчик вдруг говорит: «А давайте добавим тёмную тему, это же сейчас модно»? И ты такой сидишь, смотришь на свои пять тысяч строк CSS и понимаешь, что впереди тебя ждёт ночь весёлого копипаста, создание отдельного файла с переменными и бесконечная борьба с инверсией цветов. Реальная боль — это поддерживать два набора стилей так, чтобы ничего не поехало. Но, дружище, выдыхай. В 2026 году у нас есть инструменты, которые делают это за пару минут.

Как мы страдали раньше

Давай вспомним классику. Сначала мы использовали отдельные классы вроде .dark-theme на теге body и переопределяли переменные. Потом появились медиа-запросы @media (prefers-color-scheme: dark). Это было уже лучше, но всё равно приходилось писать кучу дублирующего кода. Ты либо создавал огромный блок в корне, либо (что ещё хуже) рассовывал эти медиа-запросы по всем компонентам.

Кстати, если ты всё ещё возишься с HEX-кодами внутри этих тем, настоятельно советую заценить статью про цветовые пространства OKLCH и OKLAB. Это небо и земля по сравнению с тем, как мы мучились раньше, пытаясь подобрать гармоничные оттенки вручную.

Как делать правильно в 2026 году

Сегодня наш лучший друг — это связка свойства color-scheme и функции light-dark(). Свойство color-scheme сообщает браузеру, что наш элемент (или вся страница) умеет работать и в светлой, и в тёмной теме. Это автоматически меняет системные цвета: скроллбары, кнопки и формы сразу становятся «правильными».

А функция light-dark() — это вообще магия. Она принимает два аргумента: первый для светлой темы, второй для тёмной. Браузер сам выбирает нужный вариант в зависимости от настроек системы или значения color-scheme. Больше никаких медиа-запросов внутри каждого селектора! Твой код становится чистым, как слеза верстальщика после удачного деплоя.

Готовый сниппет кода

Смотри, как это выглядит на практике. Минимум кода, максимум профита:


:root {
  /* Говорим браузеру, что поддерживаем обе темы */
  color-scheme: light dark;

  /* Объявляем адаптивные цвета с помощью функции light-dark() */
  /* Используем современные OKLCH для идеального контраста */
  --bg-color: light-dark(oklch(98% 0.01 200), oklch(15% 0.02 250));
  --text-color: light-dark(oklch(20% 0.02 250), oklch(95% 0.01 200));
  --accent-color: light-dark(#007bff, #3391ff);
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
  font-family: system-ui, sans-serif;
  transition: background-color 0.3s, color 0.3s; /* Плавное переключение */
}

.card {
  padding: 20px;
  border-radius: 12px;
  background: light-dark(rgba(0,0,0,0.05), rgba(255,255,255,0.05));
}

Если ты хочешь пойти дальше и сделать переключение тем еще более эффектным, посмотри, как реализовать плавные переходы страниц с помощью View Transitions API. Это позволит добавить ту самую крутую анимацию «раскрытия» тёмной темы кругом из точки клика.

Частая ошибка новичков

Самый частый затык — это когда пытаются использовать light-dark(), забыв прописать color-scheme. Запомни: без color-scheme: light dark; функция light-dark() просто не поймёт, какой из аргументов ей выбирать, и будет всегда отдавать значение для светлой темы по умолчанию.

Вторая ошибка — это ручное управление через JS с добавлением класса .dark, при этом полностью игнорируя системные настройки пользователя. В современном вебе хорошим тоном считается сначала проверить prefers-color-scheme, а уже потом давать пользователю возможность переопределить это вручную через color-scheme: dark; в инлайновом стиле тега html.

🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!

🚀 Прокачай свой код

Готовые CSS-сниппеты, разбор продвинутых фишек и эксклюзивные материалы — в нашем Telegram-канале.

Подписаться
error: Content is protected !!
Прокрутить вверх