Темный режим и как его лучше делать

15 октября 2020

Редактировать статью на Гитхабе

Dark Mode cover

Вы, наверное, уже заметили, что в последнее время все начали предлагать своим пользователям темный режим (Dark Mode), в котором в основном используются темные цвета, вместо традиционных белых и ярких тонов. Темный режим сегодня является одним из самых главных тенденций в современном дизайне пользовательского интерфейса. Операционные системы, браузеры и другие продукты, которыми мы пользуемся сегодня, уже во всю используют эту фичу.

Темный режим (он же “ночной режим”) не является новшеством, так как изначально первые компьютеры использовали монохромные ЭЛТ-мониторы, которые отображали зеленоватый текст на черном экране. Многие первые текстовые процессоры также позволяли печатать на черном фоне белым текстом. С появлением сложных настольных издательских систем с технологией WYSIWYG начался тренд светлого режима. Сделать виртуальный документ похожим на лист бумаги стал популярным. Браузеры так же приняли эту тенденцию, прописав в таблице стилей агента пользователя дефолтные базовые цвета (Chrome, Firefox, Safari). Вот почему когда открываем HTML-страницу, мы видим черный текст на белом фоне.

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

  • Уменьшение нагрузки на глаза;
  • Увеличивание видимости при слабом освещение;
  • Экономия заряда батареи;
  • Добавление акцента;

А как на счет веба? Он так же начал потихоньку переходит на темную сторону. У большенство сайтов появилась кнопка переключения ночного и дневного режима. Для реализации такого функционала обычно используются:

  • Отдельные классы;
  • Отдельные таблицы стилей;
  • Пользовательские свойства;
  • Серверные скрипты;

В зависимости от требований вашего проекта, вы можете использовать конкретные вышеперечисленные способы, так же их совмещать между собой. На примерах мы будем использовать пользовательские свойства. В начале объявляем основные глобальные цвета и переопределяем их в определенном селекторе.

:root {
--color-text: #000;
--color-back: #fff;
}

:root[data-theme='dark'] {
--color-text: #fff;
--color-back: #000;
}

body {
background-color: var(--color-back);
color: var(--color-text);
}

Остается только написать небольшой js-скрипт, который будет отвечать за изменения значения data-атрибута (в данном случае data-theme).

const button = document.querySelector('.button')

button.addEventListener('click', function () {
let theme = document.documentElement.getAttribute('data-theme')
document.documentElement.setAttribute(
'data-theme',
theme === 'dark' ? 'light' : 'dark',
)
})

Однако, при каждом обновление страницы, надо будет заново переключаться в нужный режим. Уместно было бы сохранять настройки в браузере, чтобы при следующем посещение нашего сайта показать пользователю тот режим, который он предпочел. Для этого будем использовать LocalStorage. Также для этого хорошо подходит сookies.

const button = document.querySelector('.button')
const currentTheme = localStorage.getItem('theme') || 'light'

button.addEventListener('click', function () {
const theme = localStorage.getItem('theme')
document.documentElement.setAttribute(
'data-theme',
theme === 'light' ? 'dark' : 'light',
)
localStorage.setItem('theme', theme === 'light' ? 'dark' : 'light')
})

document.documentElement.setAttribute('data-theme', currentTheme)

Теперь все работает как надо. Настройки сохраняются – пользователи радуются.

Но как быть, если пользователь предпочел темный режим в своем устройстве и ожидает увидеть в темном браузере темную страницу (что-то много стало темного 🙂 )? Многие упускают этот момент. Некоторые предпочитают, чтобы сайт отображался только в одном выбранном режиме, в то время как другие хотят чтобы он реагировал также на изменение темы их операционной системы. Как это сделать?

Не задолго до выпуска macOS Mojave, в 2018 году W3C добавила черновой вариант спецификации “Media Queries Level 5”, куда был включен новый медиа-запрос prefers-color-scheme. Он используется для определения того, светлую или темную тему использует пользователь в своем устройстве. На сегодняшний день данная функция поддерживается большинством браузеров.

Давайте воспользуемся новой фичей и немного поменяем наш функционал. До этого наш переключатель темы имел два состояния, то сейчас нам нужно три (dark, light, device). Добавим новое значение data-theme="device".

:root {
--color-text: #000;
--color-back: #fff;
}

:root[data-theme='dark'] {
--color-text: #fff;
--color-back: #000;
}

@media (prefers-color-scheme: dark) {
:root[data-theme='device'] {
--color-text: #fff;
--color-back: #000;
}
}

body {
background-color: var(--color-back);
color: var(--color-text);
}

Изменим js-скрипт

const inputs = document.querySelectorAll('input[name="theme"]')
const currentTheme = localStorage.getItem('theme') || 'device'
const input = document.querySelector(`input[id="${currentTheme}"]`)

inputs.forEach((input) => {
input.addEventListener('change', (e) => {
document.documentElement.setAttribute('data-theme', e.target.id)
localStorage.setItem('theme', e.target.id)
})
})

document.documentElement.setAttribute('data-theme', currentTheme)
input.setAttribute('checked', true)

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

Иногда бывает, что HTML-страница загружается и ждет окончание загрузки CSS файла. Вопрос, что будет, если мы изначально выбрали темный режим и сохранили настройки в браузере? Верно, как только загрузятся стили и сработает скрипт, то произойдет резкий переход с белого на черный, так как изначально наша страница имеет белый фон. Для избежания такого эффекта, есть специальный мета-тег color-scheme, который сообщает таблице стилей агента пользователя, какие цветовые схемы ему использовать по умолчанию.

<meta name="color-scheme" content="dark" />

Данную запись можно установить и в CSS:

:root {
color-scheme: light dark;
}

Для поддержки только темной темы нужно указать dark. Если поддерживаете обе темы, то dark light. Данный функционал работать почти во всех современных браузерах, кроме Firefox.

На этом пока все!

От себя хочу добавить, что темный режим делает пользовательский интерфейс разнообразнее и интереснее. Для вас это отличная возможность показать, что вы идете в ногу со временем и заботитесь обо всех своих пользователях.

А ты уже перешел на “темную сторону”?

Комментарии