Меню Закрити

Нічний режим на сайті своїми руками

Розповідає Flavio Copes

Нещодавно я змінив дизайн свого веб-сайту. Ось як він виглядав раніше:

Попередній дизайн
Попередній дизайн

Я розробив цей веб-сайт майже рік тому, вносячи багато змін протягом цього часу, так само, як робив це з будь-яким веб-сайтом.

Зрештою, дизайн мені здався застарілим: назва завелика, багато місця марнується замість того, щоб показувати вміст, і таке інше. Тому я вирішив зробити редизайн.

Новий дизайн
Новий дизайн

Значно краще! Найбільш важливі елементи вмісту стали виразнішими.

Я використав моноширинний шрифт (Inconsolata), тому що він добре пасує блогу про програмування, незважаючи на знижену прочитність і збільшений розмір сторінки через його використання, і тому що я хочу, щоб цей шрифт був на моєму сайті. Мені він подобається найбільше, а оскільки сайт є вагомою частиною моєї щоденної діяльності, я хотів, щоб усе відповідало моїм смакам.

Мені бракувало лише однієї речі — нічного режиму. У процесі зміни дизайну я приділив увагу цій опції.

Як я це зробив? По-перше, я додав Moon Emoji 🌓 на бічну панель як можливість для користувачів змінити режим зі світлого на темний.

Потім я додав сніпет JavaScript, який запускається під час його натискання. Я просто додав його до onclick обробника подій, вбудованого в HTML, без зайвих мудрувань:

<p>
  <a href="#" onclick="localStorage.setItem('mode', (localStorage.getItem('mode') || 'dark') === 'dark' ? 'light' : 'dark'); localStorage.getItem('mode') === 'dark' ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')" title="Dark/light
</p>

Це JavaScript, який виконується в onclick:

localStorage.setItem('mode', (localStorage.getItem('mode') || 'dark') === 'dark' ? 'light' : 'dark'); localStorage.getItem('mode') === 'dark' ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')

Це трохи заплутано, але по суті я перевіряю, чи параметр mode в локальному сховищі “темний” (і темний за замовчуванням, якщо це не було встановлено, — за допомогою оператора || ), і встановлюю протилежне в локальному сховищі.

Потім я призначаю dark клас елемента body HTML, тож ми можемо використовувати CSS для стилізації сторінки в темному режимі.

Інший скрипт виконується, як тільки DOM завантажується, і перевіряє, чи режим темний. Якщо так, то додає dark клас до body HTML-елемента:

document.addEventListener('DOMContentLoaded', (event) => {
  ((localStorage.getItem('mode') || 'dark') === 'dark') ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')
})

Тепер, якщо користувач змінює режим, його вибір зберігається до наступного разу, коли він завантажить сторінку.

Потім я додав багато CSS-інструкцій до CSS, усі з префіксом body.dark, як ось тут:

body.dark {
  background-color: rgb(30,34,39);
  color: #fff;
}
body.dark code[class*=language-],
body.dark table tbody>tr:nth-child(odd)>td,
body.dark table tbody>tr:nth-child(odd)>th {
  background: #282c34
}

Тепер усе має працювати! Ось мій сайт у темному режимі:

Темний (нічний) режим
Темний (нічний) режим

Я додав dark клас до елемента body за замовчуванням, щоб зробити темний режим режимом за замовчуванням:

<body class="dark">
  ...
</body>

Чому? Бо мені так більше до вподоби. Потім я провів опитування у Твіттері, і людям так теж більше сподобалося.

Але на це є також дуже проста технічна причина. Я не зберігаю вибір користувачів на сервері, тому не можу дізнатися про режим, доки не буде доступне локальне сховище.

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

Тому коли хтось переходить на іншу сторінку на моєму сайті або завантажує сторінку впершея, я не хочу показувати яскраву сторінку, поки визначаю режим. Можливо, відвідувач кодує посеред ночі в темній кімнаті.

Я б радше зробив так у світлому режимі: показати темну сторінку на кілька мілісекунд, а потім знову зробити її білою.

Специфікація Media Query Level 5, яка перебуває в стадії розробки, містить нову медіа-функцію prefers-color-scheme. Технологія Safari Technology Preview на macOS уже її підтримує, і ми можемо це використовувати, щоб дізнатися про вибір користувачем темного чи світлого режиму перегляду сторінки:

@media (prefers-color-scheme: dark) {
  body {
    background-color: black;
    color: white;
  }
}
@media (prefers-color-scheme: light) {
  body {
    background-color: white;
    color: black;
  }
}

Сподіваюся, її скоро застосують у стабільному Safari, а в майбутньому Chrome та Firefox також це підтримуватимуть.

Якщо ви знайшли помилку, будь ласка, виділіть фрагмент тексту та натисніть Ctrl+Enter.

0

Повідомити про помилку

Текст, який буде надіслано нашим редакторам: