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

Основное решение –
Для решения более сложных задач можно сохранить выбор пользователя. Благодаря локальному хранилищу у вас есть удобный инструмент для управления темами согласно предпочтениям пользователя:
// Привет, JavaScript, запомни мой выбор, ведь я могу передумать
localStorage.setItem('themePreference', 'dark');
// Мое будущее я благодарит за эту предусмотрительность
const themePreference = localStorage.getItem('themePreference');
Управление пользователями –
Теперь используем JavaScript для плавного переключения между темами. Определите предпочтения пользователя, переключайтесь между темами и применяйте решения, совместимые со всеми браузерами:
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:
if (window.matchMedia('(prefers-color-scheme)').media === 'not all') {
  // Edge, ты не вписываешься! Прощай
  document.documentElement.setAttribute('data-theme', 'default');
}
Визуализация
Когда последний раз вы хотели включить свет в солнечный день? Или погрузиться в темноту для создания уюта? Вот тут-то и пригодится переопределение настроек CSS prefers-color-scheme:
Пользовательские системные предпочтения:    🌞 (день/светло), 🌜 (ночь/темно)
Стандартная тема сайта:    💡 (светлая), 💡🔴 (темная с переопределением)
/* Трюки CSS-джедаев: ОТМЕНА НОЧИ */
@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: light;
        background: white;
        color: black;
    }
}
🌜 Пользователь выставил ТЕМНОТУ 🌜
    ⚙️ Браузер: "Задача понятна, ПЕРЕКЛЮЧАЕМ на ТЕМНОЕ!" 
        💡🔴 Ваш сайт же: "Твоей ВЕРЕ в нету я не дам!" 💡
Визуализация помогает наглядно показать, как мы управляем переключением дня и ночи на нашем сайте.
Пользовательские элементы –
Создание переключателя
Дайте пользователям волшебную палочку (буквально!). Давайте создадим элемент для переключения и украсим его иконками:
<label class="switch">
  <input type="checkbox" id="theme-toggle" checked>
  <span class="slider round"></span>
</label>
Добавим стили через CSS:
.switch {
  position: relative;
  display: inline-block;
  width: 60px; /* Можно подстроить размер */
  height: 34px; /* Подстраиваем и это */
}
.switch .slider:after {
  content: '\263E'; /* ТЕМНЫЕ СИЛЫ одобряют */
  /* Закончим стилизацию нашего ПОВЕЛИТЕЛЯ СВЕТА */
}
Синхронизация с предпочтениями пользователя
Все готово. Теперь убедимся, что наш сайт адаптируется к светлым или темным темам в зависимости от предпочтений пользователя:
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');
});


