Создание темы с темным режимом с помощью переменных CSS

В этом посте мы рассмотрим переменные CSS и медиа-запрос prefers-color-scheme, а также построим небольшой пример того, как реализовать темный режим на сайте без использования каких-либо внешних библиотек и практически без использования JavaScript.

Обзор

В последние годы «темный режим» стал широко популярен. С самого начала существования Интернета
веб-разработчики искали способы адаптации пользовательского опыта с помощью различных цветовых палитр;
В большинстве случаев это приводило к пользовательским решениям, которые в значительной степени опирались на JavaScript и работали в обход правил CSS.

Однако современный CSS теперь включает в себя функции, позволяющие разработчикам легко переопределять стили
для всего веб-сайта или веб-приложения.

Переменные CSS

Поддержка переменных CSS в браузерах, к которой шли долгие годы, была расширена примерно в 2016 году.
Теперь их поддерживают новые версии большинства современных браузеров.

Важно отметить, что эти переменные поддерживаются ванильным CSS; нет необходимости
использовать препроцессор, такой как Sass или Less.

Как видно из названия, переменные CSS позволяют хранить значения один раз и использовать их во всей таблице стилей.

Следующий пример создает две переменные в блоке body и одну в h1: body-color,

body {
  --body-color: black;
  --font-color: white;
  background-color: var(--body-color);
  color: var(--font-color);
}

h1 {
  --h1-color: gold;
  color: var(--h1-color);
}
Вход в полноэкранный режим Выход из полноэкранного режима

Обратите внимание, что переменные имеют префикс --. Так CSS распознает, что это переменные.

Затем, внутри этих же блоков, мы применяем правила CSS, такие как background-color и color, и получаем
значения переменных, передавая их в функцию var().

Хотя этот пример может показаться слишком упрощенным, вы можете увидеть потенциал: Мы можем взять эти переменные
и поместить их в глобальную область видимости:

:root {
  --body-color: black;
  --font-color: white;
  --h1-color: gold;
}

body {
  background-color: var(--body-color);
  color: var(--font-color);
}

h1 {
  color: var(--h1-color);
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Обратите внимание, что мы переместили определения переменных в блок с именем :root. Этот псевдокласс соответствует тегу <html>.
Это означает, что отсюда все правила CSS на странице будут иметь доступ к этим переменным.

Некоторые преимущества

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

Большинство веб-сайтов используют палитру из 3 или 4 цветов: основной, дополнительный и акцентный.
Мы можем создать переменную для каждого из них и ссылаться на эти переменные непосредственно в каждом другом правиле CSS.
Если вы хотите изменить палитру, просто измените определения переменных; нет необходимости обновлять каждое правило в
в каждой таблице стилей.

Переопределение переменных CSS.

Переменные CSS подчиняются тем же правилам, что и остальные CSS; таким образом, переменные можно переопределять:

<h2>This is gold</h2>
<h2 class="page1">This is green</h2>
Войти в полноэкранный режим Выйти из полноэкранного режима
:root {
  --h1-color: gold;
}

h2.page1 {
  --h1-color: green;
}

h2 {
  color: var(--h1-color);
}
Ввести полноэкранный режим Выйти из полноэкранного режима

Поскольку мы можем отменять правила CSS, добавляя специфику в селектор, мы также можем отменить
определения переменных в :root:

:root {
  --body-color: white;
  --font-color: black;
  --h1-color: gold;
}

// we only override the variables we need:
[data-dark-mode] {
  --body-color: black;
  --font-color: white;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь блок :root содержит определения переменных для «light-mode», а в блоке
блок [data-dark-mode] переопределяет переменные body-color и font-color.

Это означает, что если элемент <html> имеет атрибут data-dark-mode, то страница
будет иметь черный фон и белый шрифт, вместо белого фона и черного шрифта по умолчанию:

<!-- Light mode: -->
<html>
  <!-- ... -->

  <!-- Dark mode: -->
  <html data-dark-mode></html>
</html>
Вход в полноэкранный режим Выйти из полноэкранного режима

Атрибут data-dark-mode не является зарезервированным словом. Этот атрибут может быть
например, data-dark-theme или data-cool-dark-mode-on.

Только не забудьте приписать к атрибуту data-, так как это пользовательский атрибут.

Переключение между темным и светлым режимами

Если мы хотим позволить пользователям переключаться между светлым и темным режимами, нам понадобится пара строк
строк JavaScript. Во-первых, создайте кнопку:

<button id="dark-mode-toggle">Toggle dark mode</button>
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем добавьте слушатель событий для события «click» этой кнопки. Внутри этого слушателя событий
получите ссылку на элемент html и используйте метод toggleAttribute:

document
  .querySelector("#dark-mode-toggle")
  .addEventListener("click", function () {
    document.querySelector("html").toggleAttribute("data-dark-mode");
  });
Войти в полноэкранный режим Выйти из полноэкранного режима

Вот и все! Когда пользователь нажмет на кнопку, атрибут data-dark-mode будет переключен
в элементе <html>, перекрывая стили.

Медиазапрос «prefers-color-scheme».

Пользователи теперь могут настроить свои операционные системы (Android, iOS, MacOS и так далее) на использование
темный режим везде, где это возможно. Браузеры могут определить эту настройку с помощью медиазапросов,
в частности, медиазапрос prefers-color-scheme:

@media (prefers-color-scheme: light) {
  // detect OS-configured light-mode and apply rules
}

@media (prefers-color-scheme: dark) {
  // detect OS-configured dark-mode and apply rules
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Используя эти медиа-запросы, мы можем установить, чтобы страница всегда находилась в темном режиме, если пользователь настроил
эту опцию в своем устройстве:

:root {
  --body-color: white;
  --font-color: black;
  --h1-color: gold;
}

[data-dark-mode] {
  --body-color: black;
  --font-color: white;
}

@media (prefers-color-scheme: dark) {
  :root {
    --body-color: black;
    --font-color: white;
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

По желанию мы можем убрать кнопку переключения темного режима, если эта опция уже установлена на уровне ОС:

// ...
@media (prefers-color-scheme: dark) {
  :root {
    --body-color: black;
    --font-color: white;
  }
  #dark-mode-toggle {
    display: none;
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Самое лучшее в этом медиа-запросе то, что он устраняет необходимость использования JavaScript для применения темного режима к
странице. Но, как всегда, убедитесь, что браузеры, на которые вы рассчитываете, поддерживают медиазапрос.

Codepen

Заключение

CSS-переменные чрезвычайно полезны для стандартизации наших таблиц стилей и придания им гибкости.

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

Originally posted to https://pedromarquez.dev/blog/2022/7/dark-mode-css

Оцените статью
devanswers.ru
Добавить комментарий