Переключение между dark и default режимами в CSS

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

CSS
Скопировать код
@media (prefers-color-scheme: dark) {
  body {
    /* В целом мне нравятся темные темы, но выберем белый фон */
    background: #ffffff;
    color: #000000;
  }
}
@media (prefers-color-scheme: light) {
  body {
    /* Кто-то просил светлую тему? */
    background: #000000;
    color: #ffffff;
  }
}

Вот и все! Мы переопределили поведение prefers-color-scheme, теперь сайт выводит светлую тему тем, кто предпочитает темную, и наоборот. Похоже, что ваш сайт обрел собственную волю, не так ли?

Кинга Идем в IT: пошаговый план для смены профессии

Основное решение – Сохранение пользовательских предпочтений

Для решения более сложных задач можно сохранить выбор пользователя. Благодаря локальному хранилищу у вас есть удобный инструмент для управления темами согласно предпочтениям пользователя:

JS
Скопировать код
// Привет, JavaScript, запомни мой выбор, ведь я могу передумать
localStorage.setItem('themePreference', 'dark');

// Мое будущее я благодарит за эту предусмотрительность
const themePreference = localStorage.getItem('themePreference');

Управление пользователями – Переключение тем с помощью JavaScript

Теперь используем JavaScript для плавного переключения между темами. Определите предпочтения пользователя, переключайтесь между темами и применяйте решения, совместимые со всеми браузерами:

JS
Скопировать код
const toggleThemeBtn = document.getElementById('theme-toggle');

// Знаете, мы можем менять законы вселенной, правда?
toggleThemeBtn.addEventListener('click', () => {
  document.body.classList.toggle('dark-theme');
  const newTheme = document.body.classList.contains('dark-theme') ? 'dark' : 'light';
  localStorage.setItem('themePreference', newTheme);
  // Смотрите, мама, я меняю реальность. Я же говорил, что на это способен!
  document.documentElement.setAttribute('data-theme', newTheme);
});

План Б — Обеспечение совместимости

Некоторые элементы могут быть проблематичными (вот пример – Microsoft Edge!). К счастью, у нас есть альтернативные решения с использованием дополнительного JavaScript:

JS
Скопировать код
if (window.matchMedia('(prefers-color-scheme)').media === 'not all') {
  // Edge, ты не вписываешься! Прощай
  document.documentElement.setAttribute('data-theme', 'default');
}

Визуализация

Когда последний раз вы хотели включить свет в солнечный день? Или погрузиться в темноту для создания уюта? Вот тут-то и пригодится переопределение настроек CSS prefers-color-scheme:

Markdown
Скопировать код
Пользовательские системные предпочтения:    🌞 (день/светло), 🌜 (ночь/темно)

Стандартная тема сайта:    💡 (светлая), 💡🔴 (темная с переопределением)
HTML
Скопировать код
/* Трюки CSS-джедаев: ОТМЕНА НОЧИ */
@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: light;
        background: white;
        color: black;
    }
}
Markdown
Скопировать код
🌜 Пользователь выставил ТЕМНОТУ 🌜
    ⚙️ Браузер: "Задача понятна, ПЕРЕКЛЮЧАЕМ на ТЕМНОЕ!" 
        💡🔴 Ваш сайт же: "Твоей ВЕРЕ в нету я не дам!" 💡

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

Пользовательские элементы – Переключение тем под управлением пользователя

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

Дайте пользователям волшебную палочку (буквально!). Давайте создадим элемент для переключения и украсим его иконками:

HTML
Скопировать код
<label class="switch">
  <input type="checkbox" id="theme-toggle" checked>
  <span class="slider round"></span>
</label>

Добавим стили через CSS:

CSS
Скопировать код
.switch {
  position: relative;
  display: inline-block;
  width: 60px; /* Можно подстроить размер */
  height: 34px; /* Подстраиваем и это */
}

.switch .slider:after {
  content: '\263E'; /* ТЕМНЫЕ СИЛЫ одобряют */
  /* Закончим стилизацию нашего ПОВЕЛИТЕЛЯ СВЕТА */
}

Синхронизация с предпочтениями пользователя

Все готово. Теперь убедимся, что наш сайт адаптируется к светлым или темным темам в зависимости от предпочтений пользователя:

JS
Скопировать код
const userSystemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const themeToggle = document.getElementById('theme-toggle');

// Клянусь, не думать о худе
document.documentElement.setAttribute('data-theme', userSystemPrefersDark ? 'dark' : 'light');

// Проделали непослушную штуку
window.matchMedia('(prefers-color-scheme: dark)').addListener(e => {
  document.documentElement.setAttribute('data-theme', e.matches ? 'dark' : 'light');
});