Гид по технологиям

Добавление тёмной темы на сайт

5 min read Frontend Обновлено 30 Dec 2025
Тёмная тема на сайте — быстрая настройка
Тёмная тема на сайте — быстрая настройка

редактор кода в тёмной теме

Тёмная тема — это альтернативная цветовая схема, которая заменяет светлый фон на тёмный и делает интерфейс комфортнее в условиях низкой освещённости. Кроме эстетики, она снижает нагрузку на глаза и может экономить заряд на OLED‑экранах.

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

Что такое тёмная тема и зачем она нужна

Тёмная тема — это набор стилей, ориентированных на тёмный фон и светлый текст. Она особенно полезна:

  • в вечернее и ночное время;
  • для пользователей с повышенной чувствительностью к яркому свету;
  • на устройствах с OLED, где чёрные пиксели выключаются и экономят энергию.

Ключевой принцип: обеспечить достаточный контраст, предсказуемость интерфейса и возможность вернуть прежнюю визуализацию одним кликом.

Подготовка проекта

Убедитесь, что у вас структурированы HTML, CSS и JavaScript файлы. Ниже — минимальный пример разметки с контейнером переключателя темы.

HTML


  

  
Lorem ipsum dolor sit amet consectetur adipisicing elit. Odit deserunt sit neque in labore quis quisquam expedita minus perferendis.

Важно: оставляйте понятные id и class (например, theme__switcher), чтобы код и стили были читаемы и поддерживаемы.

Исходный интерфейс после применения HTML и CSS

CSS: базовая светлая тема

Этот CSS выступает в роли «по умолчанию» — светлая тема. Позже мы добавим классы для тёмной и светлой темы.

@import url("https://fonts.googleapis.com/css2?family=Quicksand:wght@400;700&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html { font-size: 62.5%; }

body { font-family: "Quicksand", sans-serif; }

.navbar {
  display: flex;
  padding: 2rem;
  font-size: 1.6rem;
  align-items: center;
  color: rgb(176, 58, 46);
  background-color: #fdedec;
}

.navbar span { margin-right: auto; }

.logo { font-weight: 700; }

.nav__lists {
  display: flex;
  list-style: none;
  column-gap: 2rem;
  margin: 0 2rem;
}

#theme__switcher { cursor: pointer; }

main {
  width: 300px;
  margin: 5rem auto;
  font-size: 2rem;
  line-height: 2;
  padding: 1rem 2rem;
  border-radius: 10px;
  box-shadow: 2px 3.5px 5px rgba(242, 215, 213, 0.4);
}

После применения стилей интерфейс выглядит аккуратно и готов принимать тему.

Реализация тёмной темы: классы и переключение

Идея простая: назначаем для корня документа (body или html) класс .dark или .light и переключаем набор стилей через эти классы.

CSS‑классы для тем

.dark {
  background: #1f1f1f;
  color: #fff;
}

.light {
  background: #fff;
  color: #333;
}

Рекомендация: в реальном проекте используйте CSS‑переменные (:root) и изменяйте только переменные в .dark / .light, чтобы покрыть все компоненты централизованно.

JavaScript: выбор элементов

В script.js сначала получаем ссылки на элементы управления:

// Получаем элементы для переключения темы
const themeToggle = document.getElementById("theme__switcher");
const bodyEl = document.body;

JavaScript: функция установки темы и переключатель

Ниже — улучшенная и последовательная реализация setTheme, toggleTheme и обработчика клика. Код сохраняет выбор в localStorage и правильно меняет состояние переключателя.

// Установка темы: принимает строку "dark" или "light"
function setTheme(theme) {
  bodyEl.classList.toggle("dark", theme === "dark");
  bodyEl.classList.toggle("light", theme !== "dark");

  // Визуально инвертируем иконку переключателя для обозначения тёмной темы
  themeToggle.style.filter = theme === "dark" ? "invert(75%)" : "none";

  // Сохраняем выбор пользователя
  localStorage.setItem("theme", theme);
}

// Переключатель темы
function toggleTheme() {
  setTheme(bodyEl.classList.contains("dark") ? "light" : "dark");
}

themeToggle.addEventListener("click", toggleTheme);

Этот код гарантирует предсказуемое поведение и простоту тестирования.

Интерфейс после включения тёмной темы

Улучшения: учёт системных настроек и сохранение

Два важных улучшения: 1) учитывать системную тему пользователя, 2) хранить выбор в localStorage.

Детект предпочтений системы

Используем window.matchMedia и корректно переводим результат в “dark” или “light”:

function detectPreferredTheme() {
  const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
  // Возвращаем строку для setTheme
  return prefersDarkMode ? "dark" : "light";
}

Инициализация с учётом localStorage и системных настроек

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

// Попытка прочитать ранее сохранённую тему
const storedTheme = localStorage.getItem("theme");

if (storedTheme) {
  setTheme(storedTheme);
} else {
  // Если нет сохранённой темы — применяем системную предпочтительную
  setTheme(detectPreferredTheme());
}

Таким образом: пользовательский выбор имеет приоритет; если его нет — сайт соответствует настройкам ОС.

Практические рекомендации и проверочные сценарии

Важно: тёмная тема должна быть полной — проверьте все цвета кнопок, ссылок, границ, иконок и картинок. Ниже — полезные чеклисты и тесты.

Чеклист по ролям

  • Для дизайнера:

    • Проверьте контраст текста и фона (минимум WCAG AA для текста).
    • Подготовьте альтернативные версии иконок/изображений.
    • Описать взаимодействие переключателя и состояния.
  • Для фронтенд‑разработчика:

    • Использовать CSS‑переменные для тем;
    • Обеспечить, чтобы фокусируемые элементы в тёмной теме видимы;
    • Покрыть переключатель unit‑тестами/интеграцией.
  • Для QA:

    • Проверить сохранение в localStorage;
    • Проверить поведение при смене системной темы;
    • Проверить контраст на разных разрешениях и устройствах.

Критерии приёмки

  • При клике по #theme__switcher тема переключается и состояние сохраняется в localStorage;
  • При отсутствии сохранённой темы используется prefers-color-scheme ОС;
  • Все интерактивные элементы имеют достаточный контраст и видимый фокус;
  • Иконки/изображения корректно отображаются в тёмной теме (альтернативы или фильтры).

Набор тестов (примеры)

  • TC1: первый визит пользователя — ожидаемая тема = системная предпочтительная
  • TC2: пользователь переключил на “dark” — при обновлении страницы тема остаётся “dark”
  • TC3: при смене системной темы без сохранения — страница меняет тему при следующем заходе
  • TC4: проверка контраста текста на компоненте X в тёмной теме

Альтернативные подходы и когда они уместны

  1. CSS Variables (предпочтительно): объявляете базовые цвета в :root и переписываете их в .dark. Это масштабируемо для больших проектов.
  2. Использовать data‑атрибут на (например, ) — удобно для серверной рендеринга и CSS селекторов.
  3. Серверная логика: сохранять выбор в профиле пользователя на сервере — полезно для авторизованных сервисов.

Контрпример: хранение только в куках старой реализации обычно избыточно — localStorage проще и быстрее для SPA.

Ментальные модели и эвристики

  • Модель приоритета: user choice > server setting > system preference > default.
  • Эвристика контраста: если фон тёмный, делайте акцент цветами для CTA, избегайте насыщенного чистого красного на тёмном фоне.
  • Минимизация изменений: меняйте как можно меньше DOM при переключении, чтобы уменьшить мерцание.

Мини‑методология внедрения (4 шага)

  1. Спроектируйте цветовые переменные и иконки для обеих тем.
  2. Добавьте классы .dark/.light и настройте переменные.
  3. Реализуйте setTheme/toggleTheme и инициализацию с localStorage.
  4. Проведите QA по чеклисту и выкатите на тестовую среду.

Безопасность и приватность

Использование localStorage не передаёт пользователя идентифицирующие данные на сервер автоматически. Если вы решаете синхронизировать тему с сервером — сообщите пользователю и обеспечьте TLS.

Совместимость и миграция

  • Для старых браузеров (IE11) localStorage доступен, но matchMedia может не поддерживаться — добавьте полифилы при необходимости.
  • При миграции от ручных классов к CSS‑переменным — делайте это поэтапно с feature‑флагом.

Decision flow (Mermaid)

flowchart TD
  A[Есть сохранённая тема в localStorage?] -->|Да| B[Применить saved theme]
  A -->|Нет| C[Проверить prefers-color-scheme]
  C -->|dark| D[Применить dark]
  C -->|light| E[Применить light]
  B --> F[Отобразить интерфейс]
  D --> F
  E --> F

Доступность (accessibility)

  • Проверяйте соотношение контраста (WCAG AA/AAA для важных элементов).
  • Для анимаций учитывайте prefers‑reduced‑motion и не используйте резкие мигания при переключении темы.
  • Обеспечьте видимый фокус (outline) для клавиатурной навигации.

Важно: тёмная тема — не только косметика; она должна улучшать опыт, а не ухудшать доступность.

Быстрый cheat‑sheet (сниппеты)

  • Инициализация темы:
const stored = localStorage.getItem('theme');
if (stored) setTheme(stored); else setTheme(detectPreferredTheme());
  • CSS переменная:
:root { --bg: #fff; --text: #333; }
.dark { --bg: #1f1f1f; --text: #fff; }
body { background: var(--bg); color: var(--text); }

Заключение и краткое резюме

Тёмная тема — легкий способ улучшить UX и адаптировать сайт под предпочтения пользователей. Реализация через CSS‑классы и простой JavaScript позволяет быстро внедрить переключатель, при этом учесть системные настройки и сохранить выбор пользователя.

Важно:

  • используйте CSS‑переменные для масштабируемости;
  • приоритет сохранённого выбора выше системного;
  • не забывайте про доступность и тесты.

Ключевые шаги: подготовить переменные, добавить .dark/.light, реализовать setTheme/toggleTheme, покрыть тестами и проверить контраст.

Summary:

  • Применяйте setTheme с параметром “dark”/“light”;
  • Сохраняйте выбор в localStorage;
  • Стройте проверки контраста и фокусных состояний;
  • Рассмотрите синхронизацию с профилем пользователя для авторизованных сервисов.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как пользоваться мультиметром — практическое руководство
Электроника

Как пользоваться мультиметром — практическое руководство

Исправление разрывов изображения в Linux
Linux

Исправление разрывов изображения в Linux

Отключить рекламу на Samsung Galaxy — полное руководство
Мобильные

Отключить рекламу на Samsung Galaxy — полное руководство

Как узнать устройства в Wi‑Fi через Nmap
Сеть

Как узнать устройства в Wi‑Fi через Nmap

Планирование питания с Eat This Much
Питание

Планирование питания с Eat This Much

Как предотвратить атаки Remote Access Trojan
Кибербезопасность

Как предотвратить атаки Remote Access Trojan