Mettre en place un dark mode sur son application web

Mettre en place un dark mode sur son application web

12 décembre 2021

Je pense que l'on sera d'accord pour affirmer qu'un mode dark sur une application Web est vraiment pratique. Regardons ensemble comment appliquer ce système sur votre propre site.

Document HTML

Avant toute chose, nous avons besoin d'un modèle HTML qui passera du mode light au mode dark. Pour illustrer l'exemple, nous allons créer un code simple, mais suffisant pour la démonstration.

<body>
  <div class="container">
    <h1>Dark Mode</h1>
    <ul>
      <li>Light</li>
      <li>Dark</li>
    </ul>
  </div>
</body>

Comme je vous disais, on reste simple. Un titre suivi d'une liste pour passer d'un mode à l'autre. J'ai volontairement gardé la balise body, car nous en aurons besoin un peu plus tard.

Style CSS

Donnons un peu de style à notre page HTML. De toute façon, sans ça, nous éprouverons des difficultés à effectuer un changement de light à dark.

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;700&display=swap');

:root {
  --gradient-one: #30cfd0;
  --gradient-two: #330867;
  --bg-color: #ffffff;
  --links: #000000;
}

body {
  text-align: center;
  font-family: "Poppins", sans-serif;
  background-color: var(--bg-color);
}

.container {
  width: 50%;
  margin: auto;
  padding: 100px 0;
}

.container h1 {
  font-size: 72px;
  background: linear-gradient(
    to right,
    var(--gradient-one) 0%,
    var(--gradient-two) 100%
  );
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.container ul {
  padding: 0;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
}

.container ul li {
  color: var(--links);
  cursor: pointer;
}

L'utilisation des variables est déterminant dans notre système et nous facilitera la maintenance si jamais nous souhaitons changer les couleurs plus tard.

J'applique aussi un dégradé sur notre titre afin de mieux se rendre compte du passage d'un univers à l'autre. Vous devriez obtenir quelque chose de semblable à ceci :`

Mode dark

CSS & Mode Dark

Appliquons dorénavant nos couleurs du thème dark. Pour ce qui est du choix des couleurs d'un thème sombre, prenez le temps de bien choisir, car des couleurs mal adaptées peuvent rendre l'expérience désagréable aux yeux de vos utilisateurs.

Nous allons modifier le CSS et notamment le sélecteur :root. Associons deux classes CSS avec sélecteurs avancés différentes contenant les mêmes variables, mais pas les mêmes couleurs et nous les chargeront selon un attribut data-theme posé sur le body.

[data-theme="light"] {
  --gradient-one: #30cfd0;
  --gradient-two: #330867;
  --bg-color: #ffffff;
  --links: #000000;
}

[data-theme="dark"] {
  --gradient-one: rgba(245, 107, 244, 0.79);
  --gradient-two: #efad05;
  --bg-color: #21232f;
  --links: #FFFFFF;
}

Modifions aussi notre balise HTML body :

<body data-theme="dark">
  <!-- ... -->
</body>

Si tout s'est bien passé, votre page est passé en mode dark comme ci-dessous :

Mode dark

JavaScript

Il ne reste plus qu'à effectuer un passage entre les deux modes en utilisant le menu situé sous le titre. Dans cet optique, nous allons ajouter l'attribut data-mode dans lesquels nous enregistrerons deux valeurs : light et dark.

<body data-theme="dark">
  <div class="container">
    <h1>Dark Mode</h1>
    <ul>
      <li data-mode="light">Light</li>
      <li data-mode="dark">Dark</li>
    </ul>
  </div>
</body>

Notre JavaScript va se dérouler en deux temps. Dans un premier temps, nous allons appliquer un écouteur d'évènement sur notre menu et plus précisément, sur nos li qui appellera une fonction nommée darkMode :

document.querySelectorAll('li').forEach(item => {
  item.addEventListener('click', darkMode);
});

Notre fonction darkMode :

function darkMode() {
  let body = document.querySelector('body');
  let mode = this.dataset.mode;
  body.dataset.theme = mode;
}

Le principe reste relativement simple. Au moment d'un clic sur une des li, l'écouteur d'évènement activera la fonction darkMode. Celle-ci rattrapera la valeur du data-mode compris dans la li cliquer et transféra cette même valeur au `data-theme' de body, ce qui aura pour effet de modifier l'apparence de la page en prenant les nouvelles valeurs des variables CSS.

Transitions

Maintenant que notre système est fonctionnel, vous avez remarqué que la transition est... brute. Rien de plus simple pour améliorer ceci. Ajoutons des transitions CSS aux bons endroits :

body {
  /* ... */
  transition: 350ms ease-in-out;
}

.container h1 {
  /* ... */
  transition: 350ms ease-in-out;
}

Refaites un essai et vous verrez que c'est quand même bien plus agréable désormais.

Vous pouvez retrouver le code de cet article sur mon CodePen : https://codepen.io/writecode-app/pen/NWvYoYN