Тёмная тема для сайтов на MODX
Всем привет!
Сейчас становится всё более актуально создавать сайты не только адаптивными под разные устройства, но также и с акцентом на использование в разное время суток — то есть с возможностью переключения светлой и тёмной темы.
Обратил внимание, что у многих на мобильных устройствах включена тёмная тема на постоянной основе и все приложения открываются в соответствии с системной темой. В данной статье я расскажу, как сделать сайт удобным при любом из сценариев использования тёмной темы на устройствах пользователя.
Порывшись некоторое время в интернете, я нашел несколько статей на данную тему, но изучив их повнимательнее, стало понятно, что они или упрощены (не решали в полной мере поставленной задачи), или местами написаны с ошибками. Поэтому было решено сделать свой вариант.
Для корректной работы сначала нам понадобится создать стили CSS, которые будут учитывать системную тему пользователя сайта. Ближе к началу CSS необходимо прописать следующие стили:
Мы используем CSS-переменные, которые в дальнейшем вы проставляете для ваших элементов так:
При заходе на сайт браузер будет проверять системную цветовую схему и менять цвет фона и текста в соответствии с системной темой пользователя.
Всё это прекрасно, но нам необходимо учесть сценарий, когда пользователь захочет сменить тему вручную, а также сохранить сделанный им выбор. Сперва мы преобразуем наш CSS:
Теперь нам необходимо создать небольшой скрипт на ванильном JS, можете сохранить его в отдельный файл и подключить внизу шаблона.
Теперь нам понадобится добавить переключатель на страницу. Я использовал красивый переключатель, который в основе работает через input type=checkbox, типа такого: ссылка на Codepen
В шаблоне наш переключатель может выглядеть так:
Теперь, когда наш скрипт будет переключать тему по желанию пользователя, и сохранять его выбор в куки, нам необходимо в шаблоне в тег html везде добавить class="[[!#COOKIE.theme]]" (обязательно некешируемый!):
Если в куки записан выбор пользователя — мы сразу проставим соответствующий класс при загрузке страницы и тогда браузер будет учитывать выбор пользователя на сайте, а не системную тему устройства. Обратите внимание! У вас должен быть установлен pdoTools, чтобы работала глобальная переменная [[!#COOKIE.theme]].
Крайне не рекомендую использовать контрастные цвета типа чёрного #000 и белого #fff в тёмных темах. Не выжигайте дисплей и глаза пользователя, лучше использовать мягкие цвета (тёмные оттенки серого для фона и светло серый текст вместо белого). На данную тему есть много информации в интернете и много вариантов цветов и оттенков.
Надеюсь это поможет увеличить посещаемость и время, проведённое на вашем сайте посетителями. Если у вас будут вопросы или замечания — пишите в комментарии.
Спасибо.
Сейчас становится всё более актуально создавать сайты не только адаптивными под разные устройства, но также и с акцентом на использование в разное время суток — то есть с возможностью переключения светлой и тёмной темы.
Обратил внимание, что у многих на мобильных устройствах включена тёмная тема на постоянной основе и все приложения открываются в соответствии с системной темой. В данной статье я расскажу, как сделать сайт удобным при любом из сценариев использования тёмной темы на устройствах пользователя.
Для корректной работы сначала нам понадобится создать стили CSS, которые будут учитывать системную тему пользователя сайта. Ближе к началу CSS необходимо прописать следующие стили:
html{
--bg-color: #fff;
--text-color: #333;
}
@media (prefers-color-scheme: dark) {
html{
--bg-color: #333;
--text-color: #E9EAEC;
}
}
Мы используем CSS-переменные, которые в дальнейшем вы проставляете для ваших элементов так:
body {
background-color: var(--bg-color);
color: var(--text-color);
}
При заходе на сайт браузер будет проверять системную цветовую схему и менять цвет фона и текста в соответствии с системной темой пользователя.
Всё это прекрасно, но нам необходимо учесть сценарий, когда пользователь захочет сменить тему вручную, а также сохранить сделанный им выбор. Сперва мы преобразуем наш CSS:
html{
--bg-color: #fff;
--text-color: #333;
}
html.dark{
--bg-color: #333;
--text-color: #E9EAEC;
}
@media (prefers-color-scheme: dark) {
html{
--bg-color: #333;
--text-color: #E9EAEC;
}
html.light{
--bg-color: #fff;
--text-color: #333;
}
}
Теперь нам необходимо создать небольшой скрипт на ванильном JS, можете сохранить его в отдельный файл и подключить внизу шаблона.
<script>
const el = document.documentElement;
const btn = document.getElementById("theme-toggle");
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)");
const userTheme = systemTheme.matches ? "dark" : "light";
const toggleClass = userTheme === "dark" ? "light" : "dark";
// Читаем куки
function getCookie(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
let userCurrentTheme = getCookie('theme');
// Отслеживаем переключение системной темы пользователем и установим чекбокс без перезагрузки страницы
const setThemeToggle = e => {
if (e.matches && !userCurrentTheme) {
btn.checked = true;
} else if (!userCurrentTheme) {
btn.checked = false;
}
}
// setThemeToggle(systemTheme);
systemTheme.addEventListener('change', setThemeToggle);
// Если пользователь переключил тёмную тему вручную или включена тёмная системная тема
// установим чекбокс на переключатель
if (systemTheme.matches == true && !userCurrentTheme || userCurrentTheme === "dark")
btn.checked = true;
// Чтобы переключатель визуально не дергался при загрузке страницы, отображаем его после выполнения скрипта
document.querySelector(".theme-toggle-wrapper label").style.visibility="visible";
// Отслеживаем переключение темы пользователем
btn.addEventListener("click", function() {
el.classList.toggle(toggleClass);
if (userCurrentTheme === "light" && el.classList.contains("light"))
el.classList.remove("light");
// Текущая тема, которую выбрал пользователь
userCurrentTheme = el.classList.contains(toggleClass) ? toggleClass : userTheme;
// Запишем в куки выбор пользователя
document.cookie = "theme=" + userCurrentTheme + ";path=/;";
});
</script>
Теперь нам понадобится добавить переключатель на страницу. Я использовал красивый переключатель, который в основе работает через input type=checkbox, типа такого: ссылка на Codepen
В шаблоне наш переключатель может выглядеть так:
<div class="theme-toggle-wrapper">
<input type="checkbox" id="theme-toggle" style="display: none;"/>
<label for="theme-toggle" style="visibility: hidden;">
...
</label>
</div>
Небольшое пояснение насчёт скрытия/отображения переключателя в строке:Я указал необходимые стили прямо в тегах, но их лучше перенести в CSS. На самом деле не обязательно использовать input type=checkbox, вы же можете использовать любой html-тег или какой-то другой анимированный элемент, нужно будет просто немного отредактировать JS-скрипт в соответствии с вашим выбором.
document.querySelector(".theme-toggle-wrapper label").style.visibility="visible";
Можно использовать в шаблоне конструкцию
<input type="checkbox" id="theme-toggle" [[!#COOKIE.theme:is=`dark`:then=`checked`]]/>
Но это не решает проблему «скачков» переключателя, когда у пользователя выбрана тёмная системная тема, а вручную он не делал выбор. При загрузке страницы на долю секунды будет отображаться первоначальное положение переключателя (как в светлой теме), а потом произойдет переключение в «тёмный режим». Именно для этого мы скрываем label через style=visibility: hidden;
Теперь, когда наш скрипт будет переключать тему по желанию пользователя, и сохранять его выбор в куки, нам необходимо в шаблоне в тег html везде добавить class="[[!#COOKIE.theme]]" (обязательно некешируемый!):
<html class="[[!#COOKIE.theme]]">
Если в куки записан выбор пользователя — мы сразу проставим соответствующий класс при загрузке страницы и тогда браузер будет учитывать выбор пользователя на сайте, а не системную тему устройства. Обратите внимание! У вас должен быть установлен pdoTools, чтобы работала глобальная переменная [[!#COOKIE.theme]].
Крайне не рекомендую использовать контрастные цвета типа чёрного #000 и белого #fff в тёмных темах. Не выжигайте дисплей и глаза пользователя, лучше использовать мягкие цвета (тёмные оттенки серого для фона и светло серый текст вместо белого). На данную тему есть много информации в интернете и много вариантов цветов и оттенков.
Надеюсь это поможет увеличить посещаемость и время, проведённое на вашем сайте посетителями. Если у вас будут вопросы или замечания — пишите в комментарии.
Спасибо.
Комментарии: 4
Стоит еще добавить, что если сайт использует современнный CSS фреймворк, то он уже может поддерживать тёмный режим из коробки.
Например, вот как это работает в Bootstrap 5.3.
Например, вот как это работает в Bootstrap 5.3.
Добавлю ещё пример на tailwind.
Это, конечно, очевидно. Статья рассчитана на тех, кто не пользуется указанными фреймворками.
Спасибо! Как раз что-то подобное нужно было сделать и Вы прям вовремя.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.