Добавление тёмной темы на веб‑сайт
Кратко
Тёмная тема (dark mode) улучшает читаемость в условиях низкой освещённости и может экономить заряд на OLED‑экранах. В этой статье показано, как реализовать переключатель тёмной/светлой темы с помощью CSS и JavaScript, учесть предпочтения пользователя и сохранять выбор в localStorage.
Важно: кодовые фрагменты сохранены без изменений для быстрой интеграции. Названия элементов интерфейса и пути к изображению оставлены как в исходном проекте.
Почему тёмная тема полезна
Тёмная тема заменяет светлый фон на тёмный и делает интерфейс комфортнее в сумерках и ночью. Пользователи ожидают такой опции: она улучшает восприятие контента и при правильной реализации влияет на удержание и удобство использования.
Подготовка проекта
Убедитесь, что у вас есть отдельные файлы для HTML, CSS и JavaScript и что структура проекта организована: index.html, style.css, script.js и папка с ресурсами (иконки, изображения).
Минимальные требования
- Совместимые браузеры (современные версии Chrome, Firefox, Edge, Safari).
- Семантическая HTML‑разметка.
- CSS‑переменные или классы для тем (по желанию).
HTML (структура страницы)
Используйте следующий HTML‑каркас. Элемент с id=”theme__switcher” отвечает за переключение темы.
Lorem ipsum dolor sit amet consectetur adipisicing elit.
Odit deserunt sit neque in labore quis quisquam expedita minus
perferendis.
CSS (базовая светлая тема)
Ниже приведены стили по умолчанию (светлая тема). Эти правила можно расширять: например, вынести цвета в CSS‑переменные и менять их внутри классов .dark и .light.
@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);
}
В результате интерфейс должен выглядеть примерно так:
Реализация тёмной темы с помощью CSS и JavaScript
Подход: описать визуальные различия в CSS (например, классы .dark и .light), а переключение реализовать через добавление/удаление этих классов на элементе body с помощью JS.
Создание классов тем
Простой вариант через два класса:
.dark {
background: #1f1f1f;
color: #fff;
}
.light {
background: #fff;
color: #333;
}
Для более сложных интерфейсов перенесите все цвета в CSS‑переменные и меняйте корневые переменные в .dark / .light.
Выбор интерактивных элементов
В script.js сначала выбираем элементы, с которыми будем работать:
// Get a reference to the theme switcher element and the document body
const themeToggle = document.getElementById("theme__switcher");
const bodyEl = document.body;
Переключение темы
Функция setTheme и toggleTheme обеспечивают смену классов и визуальную индикацию (фильтр для иконки):
// Function to set the theme
function setTheme(theme) {
// If the theme is "dark," add the "dark" class, remove "light" class,
// and adjust filter style
bodyEl.classList.toggle("dark", theme === "dark");
// If the theme is "light," add the "light" class, remove "dark" class,
bodyEl.classList.toggle("light", theme !== "dark");
// adjust filter of the toggle switch
themeToggle.style.filter = theme === "dark" ? "invert(75%)" : "none";
}
// Function to toggle the theme between light and dark
function toggleTheme() {
setTheme(bodyEl.classList.contains("dark") ? "light" : "dark");
}
themeToggle.addEventListener("click", toggleTheme);
После нажатия контейнера переключатель изменит тему страницы.
Улучшения на JavaScript
Ниже — два распространённых улучшения: детект системных предпочтений и сохранение выбора пользователя.
Определение системных предпочтений пользователя
Используйте window.matchMedia, чтобы подгружать тему до явного выбора пользователя:
// Function to detect user's preferred theme
function detectPreferredTheme() {
// Check if the user prefers a dark color scheme using media queries
const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
setTheme(prefersDarkMode);
}
// Run the function to detect the user's preferred theme
detectPreferredTheme();
Это помогает сделать интерфейс согласованным с системными настройками.
Сохранение выбора в localStorage
Чтобы не заставлять пользователя выбирать тему при каждом посещении, сохраняйте выбор:
function setTheme(theme) {
bodyEl.classList.toggle("dark", theme === "dark");
bodyEl.classList.toggle("light", theme !== "dark");
themeToggle.style.filter = theme === "dark" ? "invert(75%)" : "none";
// Setting the theme in local storage
localStorage.setItem("theme", theme);
}
// Check if the theme is stored in local storage
const storedTheme = localStorage.getItem("theme");
if (storedTheme) {
setTheme(storedTheme);
}
function detectPreferredTheme() {
const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
// Getting the value from local storage
const storedTheme = localStorage.getItem("theme");
setTheme(prefersDarkMode && storedTheme !== "light" ? "dark" : "light");
}
Этот подход сочетает системные предпочтения и явный выбор пользователя.
Доступность и лучшие практики
- Контраст: соблюдайте контраст текста и фона (WCAG рекомендации). Рекомендую проверить ключевые цветовые сочетания на контрастность.
- Не менять смысловые цвета: цвет статуса (ошибка/успех) должен оставаться читаемым в обеих темах.
- Анимации: избегайте резких мерцаний при переключении темы; используйте мягкий переход.
- Индикатор состояния: визуально показывайте текущую тему (aria‑атрибуты, подписи для экранных читалок).
Важно: всегда тестируйте на реальных устройствах, включая OLED‑экраны и мобильные браузеры.
Когда тёмная тема работает плохо
- Контент с большим количеством фотографий и контрастных элементов может выглядеть хуже в тёмной теме.
- Сторонние виджеты (встраиваемые виджеты, сторонние компоненты) могут не поддерживать ваши классы и требовать отдельной адаптации.
- Если вы используете много полупрозрачностей и теней, поведение может отличаться между темами.
Метод внедрения (мини‑методология)
- Проанализируйте дизайн: какие цвета и компоненты зависят от темы.
- Вынесите цвета в переменные или подготовьте набор CSS‑классов .dark/.light.
- Добавьте переключатель в DOM и напишите минимальную логику сохранения в localStorage.
- Поддержите window.matchMedia для соответствия системным настройкам.
- Проведите тесты доступности и на реальных устройствах.
- Запустите A/B‑тест (опционально) и соберите обратную связь.
Роли и чек‑лист (кто что делает)
- Дизайнер: определить палитру для тёмной и светлой тем, проверить контрастность, подготовить иконки.
- Фронтенд‑разработчик: реализовать классы тем, переключатель, сохранение выбора, обработку сторонних компонентов.
- QA: проверить сценарии переключения, сохранение в localStorage, поведение при prefers‑color‑scheme, тесты на разных устройствах.
Критерии приёмки
- Переключатель работает без перезагрузки.
- Выбор пользователя сохраняется между сессиями.
- Тема по умолчанию соответствует системным настройкам при отсутствии сохранённого выбора.
- Контраст основных элементов соответствует рекомендациям доступности.
Краткий глоссарий
- prefers‑color‑scheme: CSS/JS API для определения системной темы пользователя.
- localStorage: браузерное хранилище для сохранения настроек между сессиями.
- CSS‑переменные: удобный способ централизовать цвета и переопределять их для тем.
Резюме
- Тёмная тема повышает удобство чтения в тёмных условиях и может экономить батарею на OLED.
- Реализуйте тему через CSS‑классы или переменные и управляйте состоянием через JavaScript.
- Добавьте обнаружение prefers‑color‑scheme и сохранение в localStorage для лучшего UX.
Короткий чек: вынесите цвета, поддержите системные предпочтения, сохраняйте выбор и тестируйте доступность.
Похожие материалы
Как находить и воспроизводить GIF в Google Картинках
Сделать Windows 10 похожей на Windows 7
Исправить 0x800700e9 при загрузке Xbox Game Pass
Создать баннер YouTube в Canva
Управление Google Nest через Alexa