Переключение между 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
Теперь используем 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');
});