Dark mode

Accueil Tags Recherche

Nice touch

Certains d’entre-vous l’aurons déjà remarqué,
mais mon blog est désormais dark mode friendly ! 🎉

Je suis un grand utilisateur des dark mode pour plusieurs raisons. D’abord pour le confort des yeux avec plus de 10 heures d’écran par jour, mais aussi parce que je trouve le contraste “naturellement” plus élevé dans les thèmes sombres et que l’information y est plus rapidement identifiable (je parle ici surtout de code, évidemment). Ensuite, et même si ce n’a pas toujours été vrai, la réduction de la consommation des écrans est toujours à prendre en compte. Dernière raison enfin, et pas des moindres… Daaaaaark !! 🤘

Évolution du dark mode

Le dark mode ne date pas d’hier. On l’utilise depuis toujours dans l’informatique, et plus particulièrement dans le développement depuis plusieurs années avec l’arrivée de la vague d’éditeurs de texte avancés (Sublime Text, Atom, VSCode…). Pour plus de détails sur ses origines et son évolution, je vous renvoie au très bon article de Olivier Berni : The past, present, and future of Dark Mode.

Seulement voilà, aujourd’hui il se démocratise à grande vitesse avec son arrivée dans de nombreuses applications, ainsi que dans macOS Mojave (septembre 2018), Android 10 (mars 2019), iOS 13 (septembre 2019) ou encore Chrome 78 (octobre 2019). Le support de cette préférence utilisateur directement dans les OS et les navigateurs permet de la déployer à un tout autre niveau : directement dans les sites web.

Sa mise en place n’est pas nécessairement pertinente mais peut avoir un grand intérêt dans les sites à fort contenu éditorial, comme ce blog par exemple.

La media query prefers-color-scheme

De la même manière que vous pouvez définir un habillage CSS spécifique pour l’impression d’une page web, vous pouvez aujourd’hui en définir un pour les utilisateurs ayant activé le dark mode. Et c’est aussi simple que ça :

body {
    color: #333;
    background: #fff;
}

@media (prefers-color-scheme: dark) {
    body {
        color: #fff;
        background: #333;
    }
}

Il n’y a rien d’autre à mettre en place, c’est supporté sur les dernières versions de tous les navigateurs. Encore mieux, il n’y a même pas à s’inquiéter des dinosaures car il s’agit la uniquement de cosmétique et l’absence de support de cette media query n’est en rien un frein à l’utilisabilité du site web.

Faciliter son utilisation avec Sass

Si vous utilisez le pré-processeur Sass vous pourrez trouver assez dérangeant d’avoir à placer toutes vos media queries en dehors de vos sélecteurs imbriqués :

.block {
    display: flex;
    justify-content: center;
    padding: 0.5em;

    &__element {
        color: $color-light;
        background: $color-primary;

        &--active {
            background: $color-primary-light;
        }
    }
}

@media (prefers-color-scheme: dark) {
    .block {
        &__element {
            background: $color-secondary;

            &--active {
                background: $color-secondary-light;
            }
        }
    }
}

Nous avions déjà abordé ce problème lors de précédents articles, voici donc un tout petit mixin permettant d’inclure l’habillage de votre dark mode au bon endroit (ce qui reste je le conçois, une question de préférences) :

@mixin darkmode()
{
    @media (prefers-color-scheme: dark) {
        @content;
    }
}

.block {
    display: flex;
    justify-content: center;
    padding: 0.5em;

    &__element {
        color: $color-light;
        background: $color-primary;

        @include darkmode() {
            background: $color-secondary;
        }

        &--active {
            background: $color-primary-light;

            @include darkmode() {
                background: $color-secondary-light;
            }
        }
    }
}

Détecter le dark mode en JavaScript

Dans l’en-tête de ce blog, il y a (à ce jour, en février 2020) un canvas avec un ensemble de triangles générés à la volée. Ces triangles ont tous un fond en opacité de noir en temps normal, mais sur en dark mode ils n’étaient plus vraiment visibles (opacité de noir sur un fond gris foncé), j’ai donc voulu les passer en opacité de blanc.

Vient alors la question : comment savoir en JavaScript si l’utilisateur utilise ou non le dark mode ?

L’interface Window propose justement une méthode matchMedia(query) qui va permettre de vérifier si la page courante correspond à une media query, de la manière suivante :

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    // dark mode 
} else {
    // light mode 
}

Dès lors, vous n’avez plus aucune limite pour la mise en place de votre dark mode !

Tester avec Chrome

Petite astuce qui est toujours utile, Chrome permet d’émuler cette préférence utilisateur rapidement. Certes, vous pourriez toujours changer vos propres préférences dans le navigateur, mais quand vous voulez faire des comparaison light/dark rapidement, ce n’est vraiment pas gérable.

Pour activer cette émulation :

  • Allez dans les DevTools
  • Ouvrez le menu de commandes via ⌘ + ⇧ + P (ou Ctrl + ⇧ + P sur Windows)
  • Tapez la commande “Show Rendering” et validez par Enter

Vous aurez ensuite accès à un nouvel onglet des DevTools, dans lequel vous pourrez changer rapidement du light mode au dark mode :

Le panel Rendering des DevTools Chrome

Dernier conseil

À moins que votre dark mode n’ait été prévu dès le départ vous aurez forcément un certains nombre de modifications à faire, qui ne seront pas de simples remplacements de couleurs. N’hésitez pas à jouer avec les filtres CSS, et tout particulièrement brightness pour faire vos derniers ajustements, ils vous seront d’une grande aide pour ne pas avoir à créer d’assets supplémentaires, par exemple…

Liens :

The past, present, and future of Dark Mode
Can I Use ? prefers-color-scheme
Can I Use ? matchMedia