Kodujemy dark mode – html, css, js

Ciemne interfejsy są coraz częściej spotykane na stronach www, aplikacjach internetowych. Poniżej, w kilku krokach, pokażę jak można zakodować funkcjonalność „dark mode” na stronie internetowej przy użyciu html, css i js.

Tworzymy przykładowy markup w HTML i CSS wykorzystując stałe.

Tworzymy standardowy markup w html, z dołączonym w nagłówku plikiem stylów. W stopce dołączamy plik js.
Sam dokument zawiera nawigację zawierającą dwa przyciski: do zmiany trybu light i dark. Reszta to przykładowa treść strony.

<!DOCTYPE html>
<html lang="pl">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Dark mode - test</title>
    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap"
      rel="stylesheet" />
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <nav class="navbar">
      <ul class="dropdown">
        <li class="dropdown-item">
          <a id="light" href="#">Light</a>
        </li>
        <li class="dropdown-item">
          <a id="dark" href="#">Dark</a>
        </li>
      </ul>
    </nav>
    <main>
      <h1>Dark mode</h1>
      <p>
        Kodujemy dark mode przy użyciu html, css, js
      </p>
    </main>
    <script defer src="app.js"></script>
  </body>
</html>

W pliku css definiujemy przy użyciu stałych dwa lub więcej zestawy kolorystyczne, których chcemy użyć.


Używamy pseudoklasy: root , która odnosi się do głównego węzła dokumentu. Tu definiujemy interesujące nas stałe. 
Przy użyciu atrybutu [data] definiujemy dodatkowy zestaw stałych.   

:root {
    --black: #2a2e35;
    --white: #ffffff;
    --blue: #36c;
    --bg: var(--white);
    --text: var(--blue);
    --bg-nav: var(--blue);
    --text-nav: var(--white);
    --border-color: var(--white);
    --bg-normal: var(--blue);
}

[data-theme="light"] {
    --bg: var(--white);
    --text: var(--black);
    --bg-nav: var(--white);
    --text-nav: var(--black);
    --border-color: var(--black);
    --bg-normal: var(--blue);
}

[data-theme="dark"] {
    --bg: var(--black);
    --text: var(--white);
    --bg-nav: var(--black);
    --text-nav: var(--white);
    --border-color: var(--white);
    --bg-normal: var(--blue);
}

body {
    margin: 0;
    padding: 0;
    font-family: 'Montserrat', sans-serif;
    font-size: 16px;
    color: var(--text);
    background: var(--bg);
    transition: background 300ms ease-in-out, color 1000ms ease-in-out;
}

ul {
    list-style-type: none;
    margin: 0;
    padding: 0;
    width: auto;
    opacity: 1;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    height: 3rem;
    transition: opacity .15s ease-out;
}

a {
    text-decoration: none;
}

p {
    line-height: 2;
}

h1 {
    font-weight: 900;
    padding: 20px 0;
}

h2 {
    font-weight: 700;
    padding: 20px 0;
}

main {
    padding: 2rem;
    margin: 0 auto;
    max-width: 960px;
}

/* Navbar */

.navbar {
    min-height: 70px;
    width: 100%;
    background: var(--bg-nav);
    color: var(--text-nav);
    border-bottom: 1px solid var(--border-color);
    box-shadow: rgba(2, 8, 20, 0.1) 0px 0.175em 0.2em;
    display: flex;
    align-items: center;
}

.dropdown-item a {
    width: 100%;
    height: 100%;
    size: 0.7rem;
    padding-left: 10px;
}

.dropdown-item a::before {
    content: ' ';
    border: 1px solid var(--border-color);
    border-radius: 50%;
    width: .7rem;
    height: .7rem;
    display: inline-block;
    vertical-align: middle;
    margin-right: 10px;
    margin-bottom: 1px;
}

#dark::before {
    background: #2a2e35;
}

#light::before {
    background: #ffffff;
}

#normal::before {
    background: var(--bg-normal);
}

.active-theme {
    margin: 0 10px;
    padding: 5px 10px;
    border-radius: 5px;
    border: 1px solid var(--text-nav);
}


Ostatni etap to javascript

Przy użyciu javascript po kliknięciu w link menu podmieniamy zestaw zdefiniowanych stałych kolorów za pomocą funkcji setAttribute a jej wartość przechowujemy w localStorage przeglądarki.

const darkButton = document.getElementById('dark');
const lightButton = document.getElementById('light');
const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
const body = document.body;

if (currentTheme) {
  body.setAttribute('data-theme', currentTheme);
}

darkButton.onclick = () => {
  body.setAttribute('data-theme', 'dark');
  removeActive();
  darkButton.classList.add('active-theme');
  localStorage.setItem('theme', 'dark');
};

lightButton.onclick = () => {
  body.setAttribute('data-theme', 'light');
  removeActive();
  lightButton.classList.add('active-theme');
  localStorage.setItem('theme', 'light');
};

Korzystając z tego rozwiązania można nie tylko zrobić „dark mode” ale także zakodować dowolne zmiany schematu kolorystycznego strony www.

W podobny sposób można też manipulować wielkością fontów oraz innych elementów na stronie www.

Przedstawiony powyżej sposób to tylko jeden z możliwych wariantów, kiedy tworzymy stronę internetową od początku.
W innym wypadku należy cześć plików css istniejącej strony www zmodyfikować lub przepisać na nowo. 

Ten sposób możemy wykorzystać przy budowie  statycznych stron www jak i stron, sklepów internetowych, opartych na systemach zarządzania treścią jak np. WordPress, Drupal, Joomla itp. Jednak w tym drugim przypadku będzie to bardziej skomplikowane i czasochłonne.

autor: Marcin Jóźwiak