Автоматическое переключение тем сайта: настройка и внедрение

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Веб-разработчики и программисты
  • UX-дизайнеры и специалисты по пользовательскому интерфейсу
  • Студенты и обучающиеся в области веб-разработки

    Тёмная тема — это не просто модный тренд, а функционал, существенно повышающий удобство использования сайта. Представьте: пользователь заходит на ваш ресурс вечером, глаза устали, а тут — яркий белый экран буквально "выжигает" сетчатку! 🌙 Или наоборот: солнечным днём тёмная тема становится нечитаемой. Автоматическое переключение между светлой и тёмной темами — элегантное решение, которое превращает ваш сайт из просто хорошего в действительно заботящийся о пользователе. Давайте разберёмся, как реализовать это без лишних сложностей.

Погружаясь в мир автоматического переключения тем, вы делаете первый шаг к современной веб-разработке, где UX всегда на первом месте. На курсе Обучение веб-разработке от Skypro вы не просто научитесь создавать адаптивные интерфейсы — вы поймете, как мыслить категориями удобства пользователей. Здесь вы найдете баланс между эстетикой и функциональностью, осваивая инструменты, которые делают ваш код не просто рабочим, а впечатляющим.

Основы создания сайта с автоматическим переключением тем

Прежде чем приступить к кодированию, важно понять базовую архитектуру адаптивной темизации. Автоматическое переключение тем состоит из трёх ключевых компонентов:

  • Система определения предпочтений пользователя (системные настройки или ручной выбор)
  • Механизм хранения и применения выбранной темы
  • Визуальное оформление для каждой темы (CSS-переменные и стили)

Современные браузеры позволяют определить, какую тему предпочитает пользователь на уровне операционной системы, благодаря медиа-запросу prefers-color-scheme. Это даёт возможность автоматически применять соответствующую тему при первом посещении сайта.

Однако для полноценного UX необходимо также предоставить возможность ручного переключения и сохранять этот выбор между сессиями, даже если он отличается от системных настроек.

Алексей Петров, Frontend-разработчик Однажды я работал над проектом для IT-компании, где большинство сотрудников использовали тёмную тему в своих редакторах кода. Когда мы запустили внутренний портал с документацией в традиционном светлом дизайне, начался настоящий бунт! Разработчики жаловались на "выжигание глаз" при переключении с IDE на наш портал.

Я быстро внедрил автоматическое определение темы по системным настройкам, и проблема была частично решена. Но затем обнаружилось, что некоторые пользователи предпочитают тёмную тему только для нашего портала, но не для всей системы. Это заставило меня реализовать полноценную систему с сохранением индивидуальных предпочтений.

Самым интересным стало то, что после внедрения двойной системы (авто + ручное управление) время, проводимое на портале, увеличилось на 22%. Оказалось, комфорт восприятия напрямую влияет на вовлечённость!

Для реализации темизации необходимо структурировать CSS так, чтобы изменение темы затрагивало минимум кода. Лучшее решение — CSS-переменные (Custom Properties), которые позволяют определить набор цветов для каждой темы и применять их ко всем элементам интерфейса.

Подход Преимущества Недостатки
Отдельные CSS-файлы для тем Чистое разделение кода, легко поддерживать Дополнительные HTTP-запросы, сложнее анимировать переходы
CSS-переменные Один файл стилей, плавные переходы, динамическое переключение Не поддерживается в очень старых браузерах
Классы на body/html Простая реализация, широкая поддержка Сложнее поддерживать большие проекты, дублирование кода
Пошаговый план для смены профессии

Реализация prefers-color-scheme для определения системной темы

Медиа-запрос prefers-color-scheme — это мощный инструмент, позволяющий узнать, предпочитает ли пользователь тёмную или светлую тему на уровне своей операционной системы. 🔍 Он имеет два основных значения: light и dark.

Базовая реализация в CSS выглядит так:

CSS
Скопировать код
/* Стили для светлой темы (по умолчанию) */
:root {
--background: #ffffff;
--text: #333333;
--primary: #4285f4;
}

/* Стили для тёмной темы при системных настройках "тёмная тема" */
@media (prefers-color-scheme: dark) {
:root {
--background: #121212;
--text: #e0e0e0;
--primary: #8ab4f8;
}
}

С помощью JavaScript мы также можем определить предпочтения пользователя и реагировать на их изменение в реальном времени:

JS
Скопировать код
// Проверяем, предпочитает ли пользователь тёмную тему
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');

// Функция, которая будет вызываться при изменении настроек
function handleThemeChange(e) {
if (e.matches) {
// Пользователь предпочитает тёмную тему
document.body.classList.add('dark-theme');
} else {
// Пользователь предпочитает светлую тему
document.body.classList.remove('dark-theme');
}
}

// Вызываем функцию при загрузке
handleThemeChange(prefersDarkScheme);

// Добавляем слушатель на изменение настроек
prefersDarkScheme.addEventListener('change', handleThemeChange);

Это решение позволяет вашему сайту мгновенно адаптироваться к предпочтениям пользователя, создавая ощущение интеграции с операционной системой. Однако помните, что не все пользователи осведомлены о системных настройках темы, поэтому важно предоставить и ручное переключение.

Марина Соколова, UX-дизайнер В одном из проектов по редизайну финансовой платформы мы столкнулись с интересной проблемой. Статистика показывала, что большинство пользователей (около 65%) заходят на сайт в вечернее время, после работы. Многие жаловались на усталость глаз при просмотре бесконечных таблиц с цифрами на белом фоне.

Мы решили внедрить автоматическое переключение на тёмную тему после 19:00, основываясь на локальном времени пользователя. Это было ошибкой! Почти сразу появилось множество отзывов от людей, работающих в ярко освещённых помещениях вечером, для которых тёмная тема оказалась неудобной.

Переключившись на определение системных предпочтений через prefers-color-scheme, мы увидели рост удовлетворённости на 34%. Но настоящий прорыв случился, когда мы добавили ручной переключатель, который "помнил" выбор пользователя: показатели вовлечённости выросли на 40%, а среднее время сессии увеличилось на 3 минуты. Люди стали использовать сайт так, как им удобно, а не так, как мы решили за них.

Настройка CSS-переменных для светлой и тёмной темы

CSS-переменные (Custom Properties) — идеальный инструмент для управления темами сайта. Они позволяют определить все цветовые значения в одном месте и легко переопределить их при смене темы. 🎨

Вот расширенный пример организации переменных для двух тем:

CSS
Скопировать код
:root {
/* Базовые цвета светлой темы */
--background-primary: #ffffff;
--background-secondary: #f5f5f5;
--text-primary: #333333;
--text-secondary: #666666;
--accent-color: #4285f4;
--border-color: #e0e0e0;
--shadow: rgba(0, 0, 0, 0.1);

/* Семантические переменные */
--success: #0f9d58;
--warning: #f4b400;
--error: #db4437;

/* Переходы для плавного изменения темы */
--transition-time: 0.3s;
}

/* Тёмная тема */
[data-theme="dark"] {
--background-primary: #121212;
--background-secondary: #1e1e1e;
--text-primary: #e0e0e0;
--text-secondary: #a0a0a0;
--accent-color: #8ab4f8;
--border-color: #333333;
--shadow: rgba(0, 0, 0, 0.3);

/* Семантические переменные для тёмной темы */
--success: #81c995;
--warning: #f9d949;
--error: #f28b82;
}

/* Применение переменных к элементам */
body {
background-color: var(--background-primary);
color: var(--text-primary);
transition: background-color var(--transition-time), color var(--transition-time);
}

.card {
background-color: var(--background-secondary);
border: 1px solid var(--border-color);
box-shadow: 0 2px 4px var(--shadow);
}

button.primary {
background-color: var(--accent-color);
color: white;
}

Такой подход позволяет создать целостную систему дизайна с учетом обеих тем. Важно помнить несколько принципов при работе с темами:

  • Используйте семантические названия переменных, а не связанные с конкретными цветами
  • Проверяйте контраст для обеих тем, особенно для текста и интерактивных элементов
  • Добавляйте плавные переходы между темами с помощью CSS-transitions
  • Не забывайте про изображения и графику — они также должны адаптироваться к темам

Для работы с изображениями в разных темах можно использовать CSS-фильтры или разные наборы изображений:

CSS
Скопировать код
/* Инверсия для простой адаптации иконок к тёмной теме */
[data-theme="dark"] .icon {
filter: invert(1);
}

/* Или использование разных изображений для тем */
.logo {
background-image: url('logo-light.png');
}

[data-theme="dark"] .logo {
background-image: url('logo-dark.png');
}

Элемент UI Светлая тема Тёмная тема Рекомендации
Основной фон #ffffff #121212 Не используйте абсолютно чёрный (#000000), предпочтительнее тёмно-серый
Карточки, элементы UI #f5f5f5 #1e1e1e Обеспечьте лёгкое визуальное отличие от основного фона
Основной текст #333333 #e0e0e0 Контраст с фоном должен быть минимум 4.5:1 по WCAG
Акцентный цвет #4285f4 #8ab4f8 В тёмной теме часто требуется более светлый оттенок для того же цвета

Создание интерактивного переключателя тем на JavaScript

Хотя автоматическое определение темы по системным настройкам — отличное начало, пользователям необходима возможность ручного выбора. Интерактивный переключатель решает эту задачу и повышает удобство использования сайта. 🔄

Базовая HTML-структура переключателя может выглядеть так:

HTML
Скопировать код
<button id="theme-toggle" aria-label="Переключить тему">
<span class="light-icon">☀️</span>
<span class="dark-icon">🌙</span>
</button>

Теперь добавим JavaScript для функциональности:

JS
Скопировать код
// Получаем кнопку переключения
const themeToggle = document.getElementById('theme-toggle');

// Функция для переключения темы
function toggleTheme() {
// Проверяем текущую тему
const currentTheme = document.documentElement.getAttribute('data-theme');

// Определяем новую тему
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';

// Применяем новую тему к HTML-элементу
document.documentElement.setAttribute('data-theme', newTheme);

// Сохраняем выбор пользователя в localStorage
localStorage.setItem('user-theme-preference', newTheme);

// Обновляем вид переключателя (опционально)
updateToggleAppearance(newTheme);
}

// Обновление внешнего вида переключателя
function updateToggleAppearance(theme) {
if (theme === 'dark') {
themeToggle.classList.add('dark-mode-active');
themeToggle.setAttribute('aria-pressed', 'true');
} else {
themeToggle.classList.remove('dark-mode-active');
themeToggle.setAttribute('aria-pressed', 'false');
}
}

// Добавляем обработчик события для кнопки
themeToggle.addEventListener('click', toggleTheme);

Для более продвинутого переключателя можно реализовать дополнительные опции:

  • Анимированный переключатель (солнце/луна с плавной трансформацией)
  • Радиокнопки с тремя вариантами: светлая, тёмная или системная тема
  • Выпадающее меню с выбором из предустановленных цветовых схем
  • Автоматическое переключение по времени суток

Ключевые аспекты, о которых стоит помнить при создании переключателя тем:

  1. Доступность – переключатель должен быть доступен с клавиатуры и работать с программами чтения с экрана
  2. Обратная связь – пользователь должен чётко понимать, какая тема активна в данный момент
  3. Производительность – переключение тем не должно вызывать заметных задержек или мерцаний
  4. Согласованность – все элементы интерфейса должны корректно изменяться при смене темы

Более современный подход к созданию переключателя с использованием CSS-анимации:

CSS
Скопировать код
/* Стилизация переключателя */
.theme-toggle {
background: none;
border: none;
padding: 5px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 40px;
height: 40px;
border-radius: 50%;
}

.toggle-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: transform 0.5s, opacity 0.3s;
}

.sun-icon {
opacity: 1;
transform: translate(-50%, -50%) rotate(0);
}

.moon-icon {
opacity: 0;
transform: translate(-50%, -50%) rotate(-90deg);
}

/* Состояние при активной тёмной теме */
[data-theme="dark"] .sun-icon {
opacity: 0;
transform: translate(-50%, -50%) rotate(90deg);
}

[data-theme="dark"] .moon-icon {
opacity: 1;
transform: translate(-50%, -50%) rotate(0);
}

Сохранение выбора пользователя с помощью localStorage

Чтобы обеспечить по-настоящему качественный пользовательский опыт, необходимо сохранять выбранную тему между сессиями. Это позволит пользователям не переключать тему при каждом посещении сайта. 🔒

Механизм сохранения выбора реализуется через localStorage — это простой способ хранения данных в браузере пользователя:

JS
Скопировать код
// Функция для сохранения выбранной темы
function saveThemePreference(theme) {
localStorage.setItem('user-theme-preference', theme);
}

// Функция для получения сохранённой темы
function getSavedThemePreference() {
return localStorage.getItem('user-theme-preference');
}

// Функция для определения начальной темы
function getInitialTheme() {
// Проверяем, есть ли сохранённый выбор пользователя
const savedTheme = getSavedThemePreference();

if (savedTheme) {
// Возвращаем сохранённую тему
return savedTheme;
}

// Если нет сохранённого выбора, используем системные настройки
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
}

// По умолчанию – светлая тема
return 'light';
}

Теперь применим эту логику при загрузке страницы:

JS
Скопировать код
document.addEventListener('DOMContentLoaded', function() {
// Определяем начальную тему
const initialTheme = getInitialTheme();

// Применяем тему
document.documentElement.setAttribute('data-theme', initialTheme);

// Обновляем внешний вид переключателя
updateToggleAppearance(initialTheme);

// Добавляем слушатель для изменения системной темы
if (window.matchMedia) {
const colorSchemeQuery = window.matchMedia('(prefers-color-scheme: dark)');

// Функция-обработчик изменения системных настроек
const handleSystemThemeChange = function(event) {
// Проверяем, есть ли сохранённый выбор пользователя
const userPreference = getSavedThemePreference();

// Если пользователь не выбирал тему вручную, следуем системным настройкам
if (!userPreference) {
const newTheme = event.matches ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', newTheme);
updateToggleAppearance(newTheme);
}
};

// Добавляем слушатель
colorSchemeQuery.addEventListener('change', handleSystemThemeChange);
}
});

Этот подход создаёт трёхуровневую систему определения темы:

  1. Если пользователь явно выбрал тему — используется его выбор
  2. Если нет — используются системные настройки
  3. Если системные настройки недоступны — применяется светлая тема по умолчанию

Дополнительно можно рассмотреть несколько расширенных сценариев:

  • Сброс темы до системной настройки (удаление пользовательского выбора)
  • Тайм-аут для сохранённой темы (например, сбрасывать через месяц)
  • Синхронизация выбора между разными страницами сайта
Метод хранения Преимущества Ограничения Срок хранения
localStorage Простой API, без срока давности Ограничение ~5MB, только строки Пока пользователь не очистит данные
sessionStorage Изолирован для вкладки Удаляется при закрытии вкладки Только текущая сессия
Cookie Отправляется на сервер, гибкие настройки Ограничение ~4KB, усложненный API Настраиваемый (от сессии до лет)
IndexedDB Большой объём, сложные структуры Сложный API, избыточен для темы Пока пользователь не очистит данные

Для большинства сайтов localStorage является оптимальным вариантом благодаря простоте использования и длительному хранению данных. Однако в случае разработки приложения с серверной синхронизацией настроек пользователя, Cookie могут быть более подходящим выбором.

Реализация автоматического переключения тем на сайте — это не просто техническая фича, а проявление уважения к предпочтениям пользователей. Создавая такие адаптивные интерфейсы, вы демонстрируете внимание к деталям и заботу о комфорте посетителей. Каждый элемент — от медиа-запросов до localStorage — выполняет свою роль в создании целостного и гармоничного пользовательского опыта. Помните: лучший дизайн — тот, который незаметно подстраивается под потребности человека, делая технологии более человечными.

Загрузка...