DARK

MODE

Comment rejoindre

le côté sombre ?

Apple présente OS X Yosemite (et son dark mode) à la conférence WWDC 2014.

Le Minitel en France (et son dark mode) dans les années 1990.

Le mode sombre

283 sites web américains parmi le top 1000 offrent une double expérience utilisateur claire et sombre.
  • Le mode sombre économise de la batterie
  • Le mode sombre offre un meilleur confort pour les yeux

pas forcément

en vrai, ça dépend

qu'en sait-on ?

couleurs système

@media prefers-color-scheme

color-scheme

Night Mode

theme switcher

light-dark()

mode d'apparence

comment le modifier ?

avant d'aller plus loin...

Night Mode

préférences système

Sur MacOS, dans "Réglages Système > Apparence > Mode d'apparence"

préférences système

Sur Windows, dans "Réglages > Personnalisation > Couleurs"

Comment émuler ?

Sur Chrome

  1. Rendering > Emulate CSS media...
  2. Ctrl+Maj+P "dark"

Sur Firefox

  1. Boutons ☀ 🌙 dans l'inspecteur

On essaye ?

Modifie ton thème de couleurs dans ton OS et/ou dans ton navigateur

Night Mode

couleurs système

Palette de couleurs web proposées par défaut pour les différentes éléments : couleur de texte, couleur de fond, couleur de lien, couleur de bordure d'un bouton, etc.

couleurs système

C'est quoi ?

Ces couleurs sont notamment prévues pour s'adapter au mode d'apparence (light et dark).

couleurs système

Couleurs système en light mode

Couleurs système en dark mode

html {
  color: CanvasText;
  background-color: Canvas;
}

couleurs système

body {
  color: canvastext;
  background-color: canvas;
}

On essaye ?

Teste les couleurs système dans une page web

Night Mode

color-scheme

Indique au navigateur quel mode d'affichage est souhaité (light et/ou dark).
Le navigateur ajuste automatiquement les couleurs système, mais aussi contrôles de formulaires, scrollbars, etc.
:root {
  color-scheme: dark;
}

Le document est prévu pour s'afficher en mode dark.

color-scheme

:root {
  color-scheme: normal;
}

Le navigateur n'adapte pas les couleurs système (valeur par défaut)

:root {
  color-scheme: light;
}

Le navigateur force ses couleurs système en mode light.

:root {
  color-scheme: dark;
}

Le navigateur force ses couleurs système  en mode dark.

:root {
  color-scheme: light dark;
}

Le navigateur adapte ses couleurs systèmes selon les préférences utilisateur

color-scheme

Quelles valeurs ?

<h1>Tiens, mais quelle est ma couleur ?</h1>
:root {
  color-scheme: normal;
}

Le  navigateur n'adapte pas les couleurs (valeur par défaut)

color-scheme

normal

:root {
  color-scheme: dark;
}

Le  navigateur force ses couleurs système en mode dark.

<h1>Tiens, mais quelle est ma couleur ?</h1>

color-scheme

dark

<h1>Tiens, mais quelle est ma couleur ?</h1>
:root {
  color-scheme: light dark;
}

Le  navigateur adapte ses couleurs selon les préférences utilisateur

:root {
  color-scheme: light dark;
}

+

CSS

:root {
  color-scheme: light dark;
}

+

=

résultat

=

OS

color-scheme

light dark

color-scheme

En résumé

C'est un point de départ.
N'agit que sur les couleurs système et l'UI du navigateur, donc reste limité en terme de design.
:root {
  color-scheme: light dark;
}
body {
  color: canvastext;
  background-color: canvas;
}

On essaye ?

On ajoute color-scheme dans notre page web

Night Mode

@media (prefers-color-scheme)

Media Query permettant de détecter le Mode d'apparence de l'utilisateur. Celui-ci est indiqué soit via ses préférences système soit via son navigateur.
@media (prefers-color-scheme: dark) {
  /* ici des styles prévus pour Dark Mode */
}

Activé si les préférences utilisateur sont en mode Dark :

(on en a déjà parlé, hein ?)

@media (prefers-color-scheme)

C'est quoi ?

:root {
    --color-base: pink;
  
  @media (prefers-color-scheme: dark) {
    --color-base: hotpink;
  }
}

Si pas de préférence ou Light, alors ces valeurs sont appliquées

Sinon, celles-ci sont appliquées

@media (prefers-color-scheme)

En pratique

.card {
  color: var(--color-base);
}

Cette Card s'adapte au mode d'apparence

@media (prefers-color-scheme)

Démo

@media (prefers-color-scheme)

En résumé

Parfait pour s'adapter automatiquement aux réglages par défaut de l'utilisateur, mais pas s'il souhaite choisir manuellement son mode de couleur sur votre site.
:root {
    /* ici des couleurs (light) */
  
  @media (prefers-color-scheme: dark) {
    /* ici des couleurs (dark) */
  }
}

On essaye ?

On propose une palette de couleurs perso avec @media

Night Mode

theme switcher

Il s'agit d'un bouton permettant à l'utilisateur de choisir son thème de couleur spécifiquement pour votre site web.

dark

light

thême switcher

C'est quoi ?

<button class="theme-switcher" aria-pressed="false" type="button">
  <span class="visually-hidden">Changer le mode de couleurs</span>
  <span class="theme-icon"><!-- ici 2 SVG light et dark --></span>
</button>

Bouton "switcher"

Je clique pour activer mon choix

  1. Vérifie si le choix de thème était déjà mémorisé en localStorage.
  2. Sinon vérifie les préférences utilisateur du système.
  3. Crée ou modifie l'attribut data-theme sur <html> (valeur "light" ou "dark").
  4. Mémorise le choix en localStorage.

Clic géré via JavaScript

theme switcher

theme switcher

:root {
  --color-white: #fff;
  --color-black: #222;
}
.composant {
  color: var(--color-black);
  background-color: var(--color-white);
  
  [data-theme="dark"] & {
    color: var(--color-white);
    background-color: var(--color-black);
  }
}

Adaptation des couleurs selon l'attribut `data-theme`

Palette de couleurs

thême switcher

En action !

FINI !

toujours pas

Night Mode

light-dark()

.button {
  color: light-dark(hotpink, white);
}
Fonction CSS qui accepte deux valeurs de couleurs, et renvoie l'une ou l'autre selon les préférences utilisateur et la valeur de color-scheme.

light-dark()

C'est quoi ?

color vaut "hotpink" en lightmode et "white" en darkmode.

:root {
  color-scheme: light dark;
  --color-text: light-dark(hotpink, white);
}
body {
  color: var(--color-text);
}

color-scheme est un pré-requis

light-dark()

.burger-text-close {
  fill: var(--color-red-700);
  
  @media (prefers-color-scheme: dark) {
    fill: var(--color-red-300);
  }
}
.burger-text-close {
  fill: light-dark(var(--color-red-700), var(--color-red-300));
}

light-dark()

Moins d'imbrications

.modal {
  color-scheme: dark;
  ...
}
.burger-close-text {
  fill: light-dark(white, pink);
}

Modale forcée en mode dark (même si les préférences sont en light)

Si cet élément est dans la Modale, il sera toujours de couleur pink

light-dark()

En mode "forçage"

light-dark()

En action !

:root {
  color-scheme: light dark;
  --surface: light-dark(beige, chocolate);
  --on-surface: light-dark(chocolate, beige); 
}
body {
  background-color: var(--surface);
  color: var(--on-surface);
}

light-dark()

compatibilité

On essaye ?

On propose une palette de couleurs perso avec light-dark()

:root {
  color-scheme: light dark;
  --variable: light-dark(pink, chocolate);
}
.box {
  background-color: var(--variable);
  color: var(--***);
}

J'ai tout compris !

Super ! Alors donc du coup
on fait comment ?

Un cas concret étape par étape

Refonte du site alsacreations.fr

Une palette de couleurs aux ptits oignons !

Donner un rôle à chaque couleur primitive

À chaque rôle son usage

usage

rôle (token)

surface

aplat de couleur principal

surface-dim

aplat de couleur secondaire

layer

bloc posé sur une surface

layer-high

bloc posé au-dessus d'un bloc

on-surface

contenu posé sur une surface

primary

couleur d'accent principale

on-primary

contenu posé sur primary

on-surface-text

texte posé sur une surface

Ces rôles deviennent une convention pour chacun de nos projets

body {
  background-color: ???;
  color: ???;
}

--body-color ?

--color-base ?

--color-txt ?

body {
  background-color: var(--surface);
  color: var(--on-surface);
}
--surface: light-dark(var(--color-white), var(--color-gray-900));

light-dark() fait le job !

styles.css

on passe tout ça à la moulinette CSS

light

dark

token

surface

--color-white

--color-gray-900

surface-dim

--color-slate-100

--color-slate-800

layer

--color-slate-100

--color-slate-800

layer-high

--color-white

--color-gray-900

on-surface

--color-gray-900

--color-white

primary

--color-blue-500

identique

on-primary

--color-white

identique

on-surface-text

--color-gray-700

--color-white

:root {
  color-scheme: light dark;
  
  --surface: light-dark(var(--color-white), var(--color-gray-900));
  --on-surface: light-dark(var(--color-gray-900), var(--color-white));
  …
}

Couleurs adaptées automatiquement au mode d'apparence utilisateur

Correspond à @media (prefers-color-scheme)

:root {
  color-scheme: light dark;
  
  --surface: light-dark(var(--color-white), var(--color-gray-900));
  --on-surface: light-dark(var(--color-gray-900), var(--color-white));
  
  &[data-theme="light"] {
    color-scheme: light;
  }

  &[data-theme="dark"] {
    color-scheme: dark;
  }
}

Couleurs adaptées automatiquement au choix manuel utilisateur.
Correspond au theme switcher

Étapes résumées

/* fichier `theme.css` */
/* valeurs issues de l'UI-Kit */
:root {
  --color-pink-100: #fce7f3;
  --color-pink-300: #f9a8d4;
  --color-pink-500: #f1498f;
  --color-pink-700: #be185d;
}
/* fichier `app.css` */
/* valeurs d'exemple à adapter au projet, évidemment */
:root {
  --primary: var(--color-blue-500);
  --surface: light-dark(var(--color-white), var(--color-gray-900));
  --on-primary: var(--color-white);
  --on-surface: light-dark(var(--color-gray-900), var(--color-white));
  --link: light-dark(var(--color-blue-700), var(--color-blue-300));
  --link-hover: light-dark(var(--color-blue-900), var(--color-blue-500));
}
/* fichier `button.css` */
.button-primary {
  background: var(--primary);
  color: var(--on-primary);
}

Primitives

Valeurs de base issues de l'UI-Kit qui ne changent pas et qui sont utilisées pour définir les rôles (tokens) du projet.

Tokens (rôles)

Propriétés auxquelles des roles ont été attribués. Font référence aux primitives et peuvent s'adapter à tous les contextes (responsive, darkmode, contrastes élevés, etc.).

Composant

Les composants font référence aux tokens plutôt qu'au primitives quand c'est possible.

Exemples de composants

body {
  background: var(--surface);
  color: var(--on-surface);
}
h1, h2, h3, h4, h5 {
  color: var(--on-surface);
}
.article-summary {
  background-color: var(--layer);
  color: var(--on-surface);
}

Dark mode : en résumé

couleurs système

@media prefers-color-scheme

color-scheme

theme switcher

light-dark()

Palette qui s'adapte au Mode d'apparence... mais très limitée (sauf Canvas et CanvasText ?)

Indique au navigateur quel Mode d'apparence adopter par défaut (couleurs système, scrollbars,...)

Détecte le Mode d'apparence utilisateur (OS) et permet de s'y adapter en CSS

Fonctionnalité permettant d'allier préférences utilisateur et choix manuel

Fonction CSS très pratique pour switcher facilement les couleurs selon le mode

Et voilà !

J'ai trouvé
ça stylé !