Я Максим, веб-разработчик. Тёмная тема на сайте — давно не модная фишка для гиков, а ожидание аудитории. Люди привыкли переключать темы в телефонах, операционных системах, мессенджерах — и удивляются, когда на сайте компании такой возможности нет. Вечером, в транспорте, в тёмной комнате — ярко-белый экран раздражает. Разберём, как реализовать dark mode технически грамотно, на что обратить внимание в дизайне и какие ошибки чаще всего допускают.
Зачем бизнес-сайту тёмная тема
Первый аргумент — комфорт пользователя. Исследования показывают, что более 80 процентов пользователей смартфонов хотя бы периодически включают тёмный режим в системе. На десктопах цифра ниже, но растёт каждый год. Когда сайт не подхватывает системную настройку и бьёт белым экраном в тёмной комнате — это неприятно. Пользователь морщится, жмурится и закрывает вкладку. Это поведенческий фактор, который Яндекс фиксирует.
Второй аргумент — экономия заряда. На смартфонах с OLED-экранами (а это большинство современных моделей) тёмные пиксели потребляют значительно меньше энергии, чем белые. Для пользователя, который читает ваш каталог в метро — это ощутимая разница. Мелочь, но из таких мелочей складывается лояльность.
Третий аргумент — восприятие бренда. Сайт с качественной тёмной темой воспринимается как современный, технологичный и заботящийся о пользователях. Это особенно актуально для IT-компаний, SaaS-продуктов, креативных агентств, но и для классического бизнеса — интернет-магазинов, сервисных компаний — грамотный dark mode добавляет ощущение продуманности.
Четвёртый аргумент — доступность. Для людей с некоторыми нарушениями зрения — например, с повышенной светочувствительностью — тёмный интерфейс не просто удобство, а необходимость. Реализация dark mode — шаг в сторону инклюзивного дизайна.
Как работает переключение тем технически
Существует два подхода к переключению: автоматический (на основе системных настроек) и ручной (переключатель на сайте). В идеале нужны оба.
Автоматическое определение через CSS
CSS-медиазапрос prefers-color-scheme позволяет определить, какая тема установлена в операционной системе пользователя. Если в Windows, macOS, iOS или Android включена тёмная тема — медиазапрос это подхватит:
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #1a1a2e;
--text-color: #e0e0e0;
}
}Это работает без единой строки JavaScript. Браузер сам определяет системную настройку и применяет нужные стили. Поддерживается во всех современных браузерах.
Но автоматического переключения часто недостаточно. Пользователь может хотеть светлую тему на вашем сайте, даже если в системе тёмная — например, при чтении длинных текстов. Или наоборот: в системе светлая тема, но на вашем сайте хочется тёмную. Поэтому нужен ручной переключатель.
Ручной переключатель
Для ручного переключения добавляется класс на корневой элемент HTML через JavaScript. Нажал кнопку — класс переключился — стили обновились:
const toggle = document.querySelector('.theme-toggle');
toggle.addEventListener('click', () => {
document.documentElement.classList.toggle('dark');
const isDark = document.documentElement.classList.contains('dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
});Выбор пользователя сохраняется в localStorage, чтобы при следующем визите тема не сбрасывалась. При загрузке страницы скрипт проверяет: есть ли сохранённая настройка? Если да — применяет её. Если нет — ориентируется на системную тему.
Предотвращение мерцания
Критический момент, о котором забывают. Если скрипт переключения темы выполняется после загрузки страницы — пользователь видит вспышку: сначала светлая тема (по умолчанию), потом резкое переключение на тёмную. Это называется FOUC (Flash of Unstyled Content) и выглядит непрофессионально.
Решение — инлайн-скрипт в теге head, который выполняется до отрисовки страницы:
<script>
const theme = localStorage.getItem('theme') ||
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.classList.add(theme);
</script>Этот скрипт минимален, выполняется мгновенно и устанавливает класс темы до того, как браузер начнёт рендерить контент. Никакого мерцания.
Реализация в React и Next.js
В React-приложениях и Next.js переключение темы обычно реализуется через контекст (Context API) или через библиотеку next-themes. Библиотека next-themes решает задачу под ключ: определяет системную тему, обрабатывает переключение, сохраняет выбор, предотвращает мерцание — всё из коробки.
CSS-переменные: архитектура, которая делает темы возможными
Основа любой реализации переключения тем — CSS Custom Properties (переменные). Идея проста: все цвета на сайте задаются не напрямую, а через переменные. При переключении темы меняются только значения переменных — все элементы обновляются автоматически.
:root {
--bg-primary: #ffffff;
--bg-secondary: #f5f5f5;
--text-primary: #1a1a1a;
--text-secondary: #666666;
--accent: #2563eb;
--border: #e5e5e5;
--shadow: rgba(0, 0, 0, 0.1);
}
:root.dark {
--bg-primary: #0f0f23;
--bg-secondary: #1a1a2e;
--text-primary: #e0e0e0;
--text-secondary: #a0a0a0;
--accent: #60a5fa;
--border: #2a2a3e;
--shadow: rgba(0, 0, 0, 0.4);
}Все стили используют переменные: `background: var(--bg-primary); color: var(--text-primary);`. Переключение темы — это замена одного набора переменных на другой. Никаких дублирующих стилей, никакого хаоса.
Для крупных проектов рекомендую организовать переменные в семантические группы: цвета фона, цвета текста, акцентные цвета, границы и тени, цвета состояний (ошибка, успех, предупреждение). Это облегчает поддержку и масштабирование.
Правила дизайна тёмной темы
Тёмная тема — это не инверсия цветов. Это отдельная визуальная система, которая требует осознанного подхода.
Не используйте чистый чёрный фон
Самая частая ошибка — заменить белый фон (#ffffff) на чистый чёрный (#000000). Результат выглядит грубо и неестественно. Чистый чёрный создаёт слишком резкий контраст с текстом, глаза устают быстрее, чем на белом фоне.
Правильный подход — тёмно-серые тона с лёгким оттенком. Проверенные варианты: #0f0f23 (с синеватым оттенком — создаёт ощущение глубины), #121212 (рекомендация Material Design — нейтральный тёмно-серый), #1a1a2e (мой любимый — достаточно тёмный, но не давящий).
Текст — не чисто белый
По той же причине — слишком высокий контраст утомляет. Вместо #ffffff используйте #e0e0e0 или #d4d4d4. Разница невелика на первый взгляд, но при чтении длинных текстов — ощутима. Глаза отдыхают.
Для вторичного текста (подписи, метаданные, хинты) — ещё более приглушённый оттенок: #a0a0a0 или #8a8a8a. Это создаёт иерархию, такую же, как в светлой теме.
Тени и глубина
В светлой теме тени — основной инструмент создания глубины. Карточка с тенью «поднимается» над фоном, кнопка с тенью кажется объёмной. В тёмной теме тени не работают — тёмная тень на тёмном фоне невидима.
Вместо теней используйте разницу в яркости фона. Карточка — чуть светлее основного фона. Модальное окно — ещё светлее. Каждый уровень «поднимает» элемент, делая его чуть менее тёмным. Такой приём называется «elevation» и активно используется в Material Design.
Тонкие границы (1 пиксель, цвет на 10–15 процентов светлее фона) тоже помогают отделить элементы друг от друга.
Акцентные цвета
Яркие насыщенные цвета, которые отлично смотрятся на белом фоне, на тёмном могут выглядеть кричаще. Синий #2563eb на белом — аккуратный и профессиональный. Тот же синий на тёмном фоне — слишком яркий, «режет» глаза.
Решение — для тёмной темы используйте более мягкие, «разбавленные» версии акцентных цветов. Вместо #2563eb — #60a5fa. Вместо #dc2626 (красный ошибки) — #f87171. Насыщенность снижается, но цвет остаётся узнаваемым.
Изображения и медиаконтент
Фотографии товаров, баннеры, пользовательский контент — не меняйте их яркость автоматически. Фотография товара должна выглядеть одинаково в обеих темах. Если перетемнить изображение — пользователь может неправильно воспринять цвет товара.
Что стоит адаптировать: иконки, логотипы, иллюстрации. Если логотип тёмного цвета — на тёмном фоне он станет невидимым. Подготовьте светлую версию логотипа для dark mode.
Декоративные SVG-иллюстрации — если они используют CSS-переменные для цветов — адаптируются автоматически. Это ещё одна причина использовать CSS Custom Properties повсеместно.
Контрастность
Минимальный контраст текста к фону — 4.5:1 для обычного текста и 3:1 для крупного (по WCAG 2.1). В тёмной теме легко нарушить эти правила — серый текст на тёмно-сером фоне может быть нечитабелен.
Проверяйте контрастность инструментами: WebAIM Contrast Checker (онлайн), расширение axe DevTools для Chrome, встроенная проверка контраста в Chrome DevTools (в инспекторе элементов, при наведении на цвет текста).
Что делать с формами и интерактивными элементами
Формы ввода — отдельная головная боль в тёмной теме.
Поля ввода должны быть визуально отличимы от фона. На светлой теме белое поле на сером фоне — очевидно. На тёмной теме поле и фон сливаются, если не добавить границу или сделать поле чуть светлее фона.
Состояния фокуса, ошибки, заполненного поля — все должны быть протестированы в тёмной теме. Красная обводка ошибки, которая отлично смотрится на белом фоне, на тёмном может быть слишком агрессивной.
Кнопки — проверьте все состояния: default, hover, active, disabled. В тёмной теме hover-эффект «осветление» работает лучше, чем «затемнение», которое используется в светлой.
Тестирование: на что обращать внимание
После реализации тёмной темы пройдитесь по всем страницам сайта. Звучит очевидно, но на практике разработчики тестируют главную и пару внутренних — а потом пользователь обнаруживает белый блок посреди тёмной страницы «О компании».
Составьте чек-лист для проверки: все страницы проверены в обеих темах; переключатель работает корректно; выбор сохраняется между сессиями; нет мерцания при загрузке; все тексты читабельны; все формы видны и работоспособны; изображения не «ломаются»; нет элементов, которые «исчезают» на тёмном фоне; popup-окна и модальные блоки адаптированы; подвал и шапка корректны.
Тестируйте на реальных устройствах с включённой системной тёмной темой. Убедитесь, что автоматическое определение срабатывает правильно.
Итог
Dark mode — это знак уважения к пользователю и показатель зрелости продукта. Технически реализация занимает от нескольких часов (для простого сайта) до пары дней (для сложного интернет-магазина с десятками шаблонов). Инвестиция небольшая, а впечатление от сайта меняется значительно.
Если нужна помощь с реализацией тёмной темы для вашего сайта — обращайтесь, настрою грамотно и с учётом всех нюансов.