В production-проектах — лендингах, админ-панелях, дизайн-системах — тёмная тема часто реализуется через
@media (prefers-color-scheme: dark) с полным копированием всех переменных. Одна правка в светлой — и приходится синхронизировать тёмную. Это ломает переиспользуемость и стабильность интерфейса.Как это работает
Функция
light-dark() принимает два аргумента: первый — цвет для светлой темы, второй — для тёмной. Но без color-scheme на :root она не знает контекста.:root {
color-scheme: light dark;
}
body {
background: light-dark(white, black);
color: light-dark(black, white);
}Ключевой момент:
color-scheme можно выставить вручную — например, color-scheme: dark — и функция вернёт тёмное значение вне зависимости от system preference. Это даёт гибкость для тестирования или ручного переключения.Устранение дублирования переменных
Раньше приходилось писать два набора переменных под медиа-запросом. Теперь — один:
:root {
--bg: light-dark(white, black);
--text: light-dark(black, white);
}Типичная ошибка — забыть, что
light-dark() работает только с цветами. url() или auto внутри не поддерживаются. Для градиентов — да, для ссылок — нет.Trade-offs и fallback
Поддержка: Chrome 123+, Safari 17.2+, Firefox 130+. Для старых браузеров обязателен fallback:
background: white;
background: light-dark(white, black);
Советую внедрять в свежих проектах, где тёмная тема — полноценная схема, а не пара перекрашенных блоков. Код становится предсказуемее, а visual regression снижается.
Вывод:
light-dark() избавляет от дублирования цветовых переменных в тёмной теме, но требует контроля color-scheme и fallback для старых браузеров.