Добавление светлых и темных режимов с помощью переключателя на ваш сайт

Добавление светлых и темных режимов с помощью переключателя на ваш сайт

25 ноября 2022 г.

В настоящее время возможность переключения между светлой и темной темой стала чрезвычайно популярной в Интернете. Прошло некоторое время с тех пор, как мы начали видеть его в настольных приложениях, но теперь мы также можем видеть его каждый день на большинстве веб-сайтов, которые мы используем: Github, Stackoverflow, Twitter и т. д. Есть несколько способов реализовать это, я покажу вам свой.

Написание тем

На дворе 2022 год, мы пережили Коронавирус, и Internet Explorer окончательно умер. Я думаю, что сейчас самое время начать использовать настраиваемые свойства CSS, если вы еще этого не сделали (вы можете прочитать этот фантастический пост от Криса Койера, если вы не знакомы с ними или не понимаете, о чем я говорю).

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

body {
  --bg-color: #fff;
  --bg-color-secondary: #eee;
  --text-color: #303030;
  --text-color-secondary: #707070;
  --border-color: #eeeeee;
}

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

@media (prefers-color-scheme: dark) {
  body {
    --bg-color: #292639;
    --bg-color-secondary: #1b1928;
    --text-color: #ebeaf7;
    --text-color-secondary: #bebbd2;
    --border-color: #3a3650;
  }
}

Теперь мы можем просто использовать эти свойства в нашем CSS.

body {
  background: var(--bg-color);
  color: var(--text-color);
  /* ... */ 
}

.header {
  border-bottom: 1px solid var(--border-color);
  /* ... */ 
}

.menu-item {
  color: var(--text-color-secondary);
  /* ... */ 
}

.button {
  background: var(--bg-color-secondary);
  border: 1px solid var(--border-color);
  /* ... */ 
}

/* ... */ 

Некоторые аспекты UX

Не поймите меня неправильно; Я не UX-дизайнер. В любом случае, я чувствую себя достаточно комфортно, чтобы дать вам несколько советов относительно UX на светлых/темных темах:

Темный не черный. Помимо #000000, есть много темных цветов, на самом деле, вы можете видеть, что я не использую черный цвет в качестве фона на этом сайте. Свет тоже не обязательно белый. Есть много мест, где можно черпать вдохновение; если вы не являетесь экспертом в теории цвета, посмотрите, что делают другие сайты, или возьмите некоторые идеи из тем IDE.

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

Цвет значков SVG зависит от содержимого. Убедитесь, что вы не жестко кодируете цветовые коды в свойствах stroke или fill ваших значков SVG. Используйте currentColor в этих свойствах и позвольте каскаду CSS сделать свою работу.

Следите за изображениями контента. Не каждое изображение будет хорошо сочетаться с обеими темами. Протестируйте изображения, которые вы выбрали для своего контента, и выберите те, которые хорошо смотрятся на темном и светлом фоне. Иногда это может быть невозможно, не волнуйтесь, есть разные способы показать пользователям несколько изображений, например:

<picture>
  <source srcset="image-dark.png" media="(prefers-color-scheme: dark)" />
  <source srcset="image-light.png" media="(prefers-color-scheme: light)" />
  <img src="image-light.png" />
</picture>

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

@media (prefers-color-scheme: dark) {
  img {
    filter: brightness(0.9) contrast(1.1);
  }
}

Если вы выполните следующие действия, у вас будет две версии темы. Я знаю, что это не всегда так просто, как я описал здесь, особенно если вы не создаете свою тему с нуля, а добавляете новый вариант к существующему. Примените эти советы к своей ситуации и не сдавайтесь.

Разрешить пользователю переключаться

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

Наиболее распространенный способ сделать это — создать причудливый переключатель, но любая кнопка также подойдет. Эта статья призвана показать вам, как вы можете реализовать эту функциональность, и мы не будем сосредотачиваться на дизайне коммутатора. В любом случае, вы можете искать здесь вдохновение или взглянуть на код моего собственного переключателя. этот Кодепен:

https://codepen.io/artberri/pen/abYzjQR?embedable=true

После того, как мы разработали наш переключатель или кнопку, нам нужно реализовать функциональность с помощью javascript. Мы сможем сделать это с помощью этого простого кода:

// Get the button element
const btn = document.querySelector(".your-button-or-switch-class");
// Detect if user preference is dark
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
// On button click
btn.addEventListener("click", function() {
  // Get users preference
  const userSystemPreference = prefersDarkScheme.matches ? "dark" : "light";
  // Choose the class that will be added or removed
  const toggleClass = userSystemPreference === "dark" ? "light" : "dark";
  // Add or remove the class on the <html> element
  document.documentElement.classList.toggle(toggleClass);
});

Как видите, мы добавим или удалим класс dark в элемент html, если пользователь предпочитает светлую тему, и мы будем переключать light. code> class в случае, если их предпочтительный вариант темный. На данный момент это не вызовет никакого эффекта, но он будет с этим простым дополнением к нашему CSS:

.dark body {
  --bg-color: #292639;
  --bg-color-secondary: #1b1928;
  --text-color: #ebeaf7;
  --text-color-secondary: #bebbd2;
  --border-color: #3a3650;
}

@media (prefers-color-scheme: dark) {
  .light body {
    --bg-color: #fff;
    --bg-color-secondary: #eee;
    --text-color: #303030;
    --text-color-secondary: #707070;
    --border-color: #eeeeee;
  }
}

При этом наш сайт будет загружаться с предпочитаемой пользователем темой, и это позволит им переключаться, если они захотят. Итак, мы закончили? Еще нет.

Сохранение предпочтений пользователя

Есть только одна вещь, которой нам не хватает; нам нужно сохранить предпочтения пользователя, чтобы они сохранялись между сеансами или навигацией по страницам. Я думаю, что проще всего сохранить его в локальном хранилище браузера, и для этого нам нужно изменить код Javascript, который я показал вам ранее.

const btn = document.querySelector(".your-button-or-switch-class");
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
btn.addEventListener("click", function() {
  const userSystemPreference = prefersDarkScheme.matches ? "dark" : "light";
  const toggleClass = userSystemPreference === "dark" ? "light" : "dark";
  document.documentElement.classList.toggle(toggleClass);

  // Obtain which is the user's current preference for our website
  const userCurrentPreference = document.documentElement.classList.contains(toggleClass)
    ? toggleClass
    : userSystemPreference;
  // Save it in local storage
  localStorage.setItem("mode", mode);
});

Эта небольшая модификация получит текущий режим на основе класса документа html (или его отсутствия) и сохранит его в локальном хранилище. После сохранения настройки нам нужно убедиться, что мы используем ее при каждой загрузке страницы, и мы сделаем это, выполнив этот код в <head> нашей веб-страницы перед загрузкой любого CSS:< /p>

<script type="text/javascript">
  (function () {
      var userCurrentPreference = localStorage.getItem("mode");
      if (userCurrentPreference === "dark") document.documentElement.classList.toggle("dark");
      else if (userCurrentPreference === "light") document.documentElement.classList.toggle("light");
  })();
</script>

Хотите знать, почему я прошу вас добавить синхронный код Javascript прямо в head вашего HTML? Добавляя этот фрагмент асинхронно или после загрузки HTML и CSS, вы рискуете получить вспышку неправильного цвета темы (это означает, что неправильная тема может отображаться в течение нескольких миллисекунд). На мой взгляд, перегрузка этого кода того стоит. Некоторые люди используют решение на основе файлов cookie, чтобы избежать этого кода, но его необходимо реализовать на стороне сервера, что невозможно, если у вас есть статический сайт, как у меня.

Я надеюсь, вам понравится читать; не забудьте поделиться им в предпочитаемой вами социальной сети, если вы это сделаете.


Также опубликовано здесь


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE