Как на JS реализовать «темную тему», которая автоматически активируется в зависимости от настроек системы пользователя?
Для реализации тёмной темы, которая автоматически активируется в зависимости от системных настроек пользователя, в JavaScript используется медиазапрос `prefers-color-scheme` через API `window.matchMedia`.
**Базовая реализация**
Сначала определите стили для светлой и тёмной темы в CSS:
css
:root {
—bg-color: #ffffff;
—text-color: #000000;
}
[data-theme=»dark»] {
—bg-color: #1a1a1a;
—text-color: #ffffff;
}
body {
background-color: var(—bg-color);
color: var(—text-color);
}
Затем в JavaScript определите текущие системные настройки:
javascript
const prefersDark = window.matchMedia(‘(prefers-color-scheme: dark)’);
function applyTheme(isDark) {
document.documentElement.setAttribute(‘data-theme’, isDark ? ‘dark’ : ‘light’);
}
// Применяем тему при загрузке страницы
applyTheme(prefersDark.matches);
// Слушаем изменения системной темы в реальном времени
prefersDark.addEventListener(‘change’, (event) => {
applyTheme(event.matches);
});
**Сохранение пользовательского выбора**
Если вы хотите дать пользователю возможность переключать тему вручную и сохранять его выбор, используйте `localStorage`:
javascript
const savedTheme = localStorage.getItem(‘theme’);
const prefersDark = window.matchMedia(‘(prefers-color-scheme: dark)’);
function applyTheme(isDark) {
document.documentElement.setAttribute(‘data-theme’, isDark ? ‘dark’ : ‘light’);
}
// Приоритет: сохранённый выбор → системная настройка
if (savedTheme) {
applyTheme(savedTheme === ‘dark’);
} else {
applyTheme(prefersDark.matches);
}
// Кнопка переключения
document.getElementById(‘theme-toggle’).addEventListener(‘click’, () => {
const currentTheme = document.documentElement.getAttribute(‘data-theme’);
const newTheme = currentTheme === ‘dark’ ? ‘light’ : ‘dark’;
applyTheme(newTheme === ‘dark’);
localStorage.setItem(‘theme’, newTheme);
});
// Реакция на изменение системной темы (если пользователь не выбирал вручную)
prefersDark.addEventListener(‘change’, (event) => {
if (!localStorage.getItem(‘theme’)) {
applyTheme(event.matches);
}
});
**Альтернатива через CSS**
Если JS-логика не нужна, можно использовать только CSS-медиазапрос:
css
@media (prefers-color-scheme: dark) {
body {
background-color: #1a1a1a;
color: #ffffff;
}
}
**Важные нюансы**
— Метод `addEventListener(‘change’, …)` поддерживается в современных браузерах. В старых используйте `addListener` (устарел).
— Чтобы избежать мерцания при загрузке, вставьте скрипт определения темы в « до загрузки стилей.
— Для SSR-приложений (Next.js, Nuxt) используйте куки вместо `localStorage`, чтобы тема применялась ещё на сервере.
Такой подход обеспечивает плавную интеграцию с системными настройками и хороший пользовательский опыт.
