Тёмная тема для сайтов на 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
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Например, вот как это работает в Bootstrap 5.3.