Тёмная тема на сайте: как сделать правильно (CSS variables, prefers-color-scheme)
Тёмная тема перестала быть просто модным трендом — теперь это обязательная функция для любого современного сайта. Она снижает нагрузку на глаза в условиях слабого освещения, экономит заряд батареи на мобильных устройствах и просто предоставляет пользователям выбор. В этой статье мы разберём, как правильно реализовать тёмную тему, учитывая системные настройки и сохраняя выбор пользователя.
1. Подготовка: CSS-переменные для тем
Ключ к удобному переключению тем — использование CSS-переменных (custom properties). Они позволяют централизованно управлять цветовой схемой.
:root {
/* Цвета светлой темы */
--bg-color: #ffffff;
--text-color: #333333;
--heading-color: #2c3e50;
--section-bg: #f8f9fa;
--shadow-color: rgba(0, 0, 0, 0.1);
}
[data-theme="dark"] {
/* Цвета тёмной темы */
--bg-color: #121212;
--text-color: #e0e0e0;
--heading-color: #bb86fc;
--section-bg: #1e1e1e;
--shadow-color: rgba(0, 0, 0, 0.3);
}
Совет по выбору цветов
Для тёмной темы лучше использовать не чистый чёрный (#000000), а тёмно-серые оттенки. Это снижает контраст и делает интерфейс более комфортным для глаз. Популярные варианты: #121212, #1e1e1e, #212121.
Применение переменных в CSS:
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s ease, color 0.3s ease;
}
h1, h2, h3 {
color: var(--heading-color);
}
.card {
background: var(--section-bg);
box-shadow: 0 2px 4px var(--shadow-color);
}
2. Определение системных предпочтений
Медиазапрос prefers-color-scheme позволяет определить, какую тему — светлую или тёмную — предпочитает пользователь в настройках своей ОС.
/* Автоматическое применение тёмной темы */
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #121212;
--text-color: #e0e0e0;
/* остальные переменные тёмной темы */
}
}
Важное ограничение
Медиазапрос prefers-color-scheme не позволяет переопределить выбор пользователя на самом сайте. Для этого потребуется JavaScript.
Комбинированный подход:
Лучше всего использовать медиазапрос как основу, но позволять пользователю переопределить выбор:
/* Светлая тема по умолчанию */
:root {
--bg-color: #ffffff;
/* остальные переменные светлой темы */
}
/* Тёмная тема по системным настройкам */
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg-color: #121212;
/* остальные переменные тёмной темы */
}
}
/* Принудительная тёмная тема */
[data-theme="dark"] {
--bg-color: #121212;
/* остальные переменные тёмной темы */
}
/* Принудительная светлая тема */
[data-theme="light"] {
--bg-color: #ffffff;
/* остальные переменные светлой темы */
}
3. Переключатель темы с JavaScript
Для реализации переключателя темы нам понадобится небольшой JavaScript-код, который будет:
- Определять текущую тему (учитывая системные настройки)
- Переключать тему при клике
- Сохранять выбор пользователя (в localStorage)
- Восстанавливать выбор при загрузке страницы
HTML для переключателя:
<div class="toggle-container">
<label class="toggle-switch">
<input type="checkbox" id="theme-toggle">
<span class="slider"></span>
</label>
<span id="theme-status">Тёмная тема</span>
</div>
JavaScript-код:
document.addEventListener('DOMContentLoaded', function() {
const toggle = document.getElementById('theme-toggle');
const themeStatus = document.getElementById('theme-status');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
// Проверяем сохранённую тему или системные настройки
const currentTheme = localStorage.getItem('theme') ||
(prefersDark.matches ? 'dark' : 'light');
// Применяем текущую тему
if (currentTheme === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
toggle.checked = true;
themeStatus.textContent = 'Тёмная тема';
} else {
document.documentElement.setAttribute('data-theme', 'light');
toggle.checked = false;
themeStatus.textContent = 'Светлая тема';
}
// Обработчик переключения
toggle.addEventListener('change', function() {
if (this.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
themeStatus.textContent = 'Тёмная тема';
} else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light');
themeStatus.textContent = 'Светлая тема';
}
});
// Следим за изменением системных настроек
prefersDark.addEventListener('change', e => {
if (!localStorage.getItem('theme')) {
if (e.matches) {
document.documentElement.setAttribute('data-theme', 'dark');
toggle.checked = true;
themeStatus.textContent = 'Тёмная тема';
} else {
document.documentElement.setAttribute('data-theme', 'light');
toggle.checked = false;
themeStatus.textContent = 'Светлая тема';
}
}
});
});
4. Особенности дизайна для тёмной темы
Простая инверсия цветов — плохая практика. Вот что нужно учитывать при создании тёмной темы:
Цветовые рекомендации:
- Снижайте контраст — яркий текст на чисто чёрном фоне утомляет глаза
- Используйте тёплые серые оттенки вместо холодных
- Уменьшайте насыщенность цветов в тёмной теме на 10-20%
- Избегайте чистого белого — используйте слегка приглушённые оттенки
Типографика:
- Увеличьте межстрочный интервал (line-height) на 5-10%
- Сделайте шрифт немного тоньше — жирные начертания могут "перегружать" тёмный интерфейс
- Проверьте читаемость — контраст должен быть не менее 15:1 для основного текста
Тени и эффекты:
- Замените тени на свечение — тени плохо видны на тёмном фоне
- Используйте более прозрачные overlay-элементы
- Добавьте тонкие границы для разделения элементов
5. Тестирование и специальные случаи
Тестирование в разных условиях:
- Проверьте в разных браузерах — реализация может отличаться
- Тестируйте на реальных устройствах — особенно на OLED-экранах
- Проверьте системные настройки — изменяя тему ОС
- Убедитесь в сохранении выбора после обновления страницы
Специальные элементы:
Некоторые элементы требуют особого внимания при реализации тёмной темы:
/* Стилизация scrollbar */
::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-track {
background: var(--section-bg);
}
::-webkit-scrollbar-thumb {
background: #555;
border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
background: #888;
}
/* Стили для изображений в тёмной теме */
[data-theme="dark"] img {
filter: brightness(0.9) contrast(1.1);
opacity: 0.9;
}
/* Особые стили для SVG */
[data-theme="dark"] .icon {
fill: #bb86fc;
}
Полезные ресурсы
- MDN: prefers-color-scheme — документация медиазапроса
- Material Design: Dark theme — рекомендации от Google
- Dark Mode Design — лучшие практики дизайна
- Полное руководство по тёмной теме на CSS-Tricks
Правильно реализованная тёмная тема — это не просто инверсия цветов, а продуманный дизайн-подход, который учитывает особенности восприятия в условиях низкой освещённости. Используя CSS-переменные, медиазапросы и JavaScript, вы можете создать удобный механизм переключения, который будет уважать выбор пользователя и системные настройки.



