Thème et dark mode en CSS natif grâce aux customs properties !

Johnathan MEUNIER
Just-Tech-IT
Published in
6 min readApr 22, 2021

Grâce aux customs properties (propriétés personnalisées CSS en français), fonctionnalité récente en CSS, il n’a jamais été si simple de mettre en place un système de thème, et donc de dark mode sur son site web !

Photo by Zac Ong on Unsplash

TL;DR : Utilisez les custom property scopé via un data-theme afin d’interpréter les variables à la runtime et non à la build. Démo

Les thèmes n’ont jamais été aussi populaires, beaucoup de sites web importants proposent un dark mode, même GitHub s’y est mis récemment ! Cependant, il n’est pas aussi évident d’en mettre un en place si votre application n’a pas été pensée dans ce sens. Pas d’inquiétude, nous allons voir ensemble les bonnes pratiques à mettre en place tout de suite et comment repasser sur votre application, que nous utilisiez un pré-processeur tel que SASS ou LESS ou même une framework tel que React.

La méthode que je vous propose se base entièrement sur les customs properties CSS, qui peuvent s’apparenter à des variables qui seront interprétées à la runtime et non à la compilation. Cette différence majeure permet de faire ce qu’un pré-processeur est incapable.

Rappel sur les propriétés personnalisées CSS

Voici la définition proposée par MDN :

Les propriétés personnalisées CSS (custom properties en anglais, aussi parfois appelés variables CSS) sont des entités définies par les développeurs ou les utilisateurs d’une page Web, contenant des valeurs spécifiques utilisables à travers le document. Elles sont initialisées avec des propriétés personnalisées (par exemple --main-color: black;) et accessibles en utilisant la notation spécifique var() (en-US) (par exemple : color: var(--main-color);).

En d’autres termes, les customs properties nous permettent de créer nos propres variables CSS nativement.

Une propriété customs s’applique sur un élément. Par convention, on voit très souvent les propriétés déclarés sur :root. Par exemple :

Vous pouvez déclarer des customs properties sur n’importe quel sélecteur.

Il existe donc une notion d’héritage et de priorité des sélecteurs, au même titre que n’importe quelle propriété CSS (d’où le terme de custom property).

Par soucis de simplicité, nous les appellerons des variables CSS par la suite, car nous allons utiliser les customs propriétés seulement dans ce but dans la suite de l’article.

Une variable est très facile à utiliser grâce au mot clés var :

Avec var(), on peut également définir des valeurs par défaut (de secours), qui seront utilisées si la variable demandée n’est pas disponible : var( — widthTime, 100px).

Nommer correctement ses variables CSS

Je voudrais également faire un point rapide sur le nommage des variables en CSS. Je vous conseille fortement de nommer vos variables selon leur raison d’exister et non pour ce qu’elles font.

Si la couleur principale de votre application est un bleu sombre (par exemple #26547C), votre variable ne doit pas être — blue: #26547C; mais bien — primary: #26547C;

Pourquoi ? Imaginez que votre charte graphique change soudainement et au lieu d’avoir un joli bleu en couleur principale, elle devient verte. Votre application serait remplie de variable nommée “blue” qui au final renverrait du vert …

Il est également plus facile d’indiquer dans une classe où l’on souhaite mettre du texte en avant ou un lien, d’utiliser une variable — emphasis ou — link que la couleur qu’elle cible. C’est exactement le même principe pour les tailles, il ne serait pas logique de nommer sa variable — width1200 : 1200px;

Je vous conseille également le très bon site Coolors pour générer vos palettes de couleurs !

Et la magie opère !

Attaquons le vif du sujet !

Nous allons dans un premier temps déclarer une custom data attribut sur le body. Cette donnée aura pour but de déterminer le thème utilisé actuellement.

Attribut data-theme au plus haut niveau

Puis nous allons déclarer la liste des couleurs que l’on va utiliser en les nommant de façon fonctionnelle. Nous allons donc déclarer une couleur :

Variables de couleurs light mode
  • primaire (primary)
  • secondaire (secondary)
  • de mise en avant (emphasis)
  • de fond (background)
  • de fond en avant (backgroundEmphasis)

Nous allons déclarer une deuxième fois cette liste mais cette fois ci pour le mode sombre :

Variables de couleurs dark mode

Vous pouvez évidemment déclarer autant de liste de couleurs que vous souhaitez.

Puis nous allons créer un bouton. Lorsqu’il sera cliqué, il inversera la valeur du data-theme pour passer de light à dark.

Bouton d’activation du dark mode

Si vous souhaitez gérer plus d’un thème, il est tout à faire possible de proposer une liste déroulante avec autant de thème que de liste de couleurs que vous avez renseigné précédemment.

La persistence du thème choisi est à gérer selon votre environnement. Il est important de stocker, le thème courant, par exemple dans un localStorage, une contexte API, un store redux, ou autre.

Et voici une démo complète :

Automatiser le dark mode

Au lieu d’utiliser un data-theme et de donner la possibilité à l’utilisateur de changer le thème, il est possible de détecter son thème système et de s’adapter en fonction.

Le système est en thème sombre
Le système est en thème clair

Et si j’utilise SASS ?

Je vous conseille de passer toutes vos variables SASS en custom properties. L’outil de recherche & remplacement de Visual Studio Code sera votre ami :

Search & Replace

Grâce à cela, vos variables seront calculées à l’interprétation et non à la compilation, la valeur de vos variables peut donc être dynamique comme nous venons de voir.

Aller plus loin ? Avec framework ? React ? Pourquoi pas des styled components ?

L’idéal serait de stocker l’information du thème actif dans le localStorage ou via redux, la context API, etc selon la technologie que vous utilisez. En effet, sans cela, à chaque changement de page le thème revient par défaut.

Si vous utilisez déjà les styled components en React, l’implémentation est très similaire. Smashing Magazine propose un article complet, pour mettre en place un dark mode dans cet environnement. Cependant, je ne suis pas spécialement pour cette pratique. Si un jour vous souhaitez migrer de framework ou tout simplement ne plus utiliser de framework, la charge de travail pour sortir tout ce qui a été fait via les styled components sera énorme. Il n’est pas indispensable de passer par des styled components pour mettre en place le theme.

Compatibilité

Malheureusement, la plupart des notions que nous avons abordées ne sont pas disponibles sur Internet Explorer. Cependant, Microsoft a annonce la fin du support d’Internet Explorer pour le 17 aout 2021 sur ses propres applications M365, donc cette solution reste largement envisageable.

Conclusion

Ressources utiles :

--

--