La Cascade

Un peu de tout sur CSS, HTML, SVG et JS,traduit du web anglophone
Rechercher

OKLCH en CSS, des palettes de couleurs accessibles et cohérentes

par Cristian Diaz, 18 septembre 2023, css, couleur, design, article original paru le 10 août 2023 dans le blog de LogRocket

Le nouveau modèle de couleur OKLCH offre une façon intuitive et cohérente de créer des couleurs pour le web.


Les couleurs jouent un rôle important dans le design web, mais créer une palette de couleurs peut paraître une tâche intimidante pour les développeurs et designers. De nombreux facteurs entrent en compte lorsqu'on conçoit une palette de couleurs : la marque (branding), l'information que vous souhaitez faire passer, le maintien d'une luminosité cohérente à travers les différentes couleurs, le contraste entre les ombres, la façon dont les couleurs s'affichent en mode sombre ou lumineux, etc.

CSS propose plusieurs fonctions de couleurs, mais plusieurs sont difficiles à utiliser ou créent des résultats incohérents. Dans cet article, nous allons explorer un nouveau modèle de couleur, oklch(), conçu pour offrir une façon intuitive et cohérente de créer des couleurs pour le web.

Table des matières :

Le modèle de couleurs Display P3

Lorsque le module de couleur CSS de niveau 4 est arrivé au stade recommandation en 2022, il a ajouté de nouveaux espaces de couleur. Les espaces de couleur sont, en gros, les représentations graphiques de groupes de couleurs disponibles sur un appareil qui accepte une gamme donnée de couleurs. Par exemple, l'espace de couleur sRGB est disponible sur la plupart des appareils depuis un certain temps. Les fonctions de couleur comme RGB et HSL créent des couleurs avec cet espace de couleurs.

Aujourd'hui, certains appareils acceptent l'espace de couleur Display P3, conçu par Apple, qui offre à peu près 50% de couleurs de plus que sRGB :

sRBG Display P3 Color Models
Le spectre de couleurs, montrant comment se recouvrent les modèles de couleur sRGB et Display P3. L'espace Display P3 offre plus de couleurs que sRGB ; crédit image : What’s new in CSS – Apple Worldwide Developers Conference.

Le module CSS Couleur 4 propose de nouvelles fonctions de couleurs avec l'espace de couleurs Display P3 : LCH, OKLCH, LAB et OKLAB. Pour voir l'étendue de couleurs qu'offre Display P3 il vous faudra un appareil qui puisse afficher ces couleurs. Cela dit, vous pouvez toujours en profiter même si votre appareil utilise l'espace de couleur sRGB. S'il ne peut pas rendre une couleur en particulier, le navigateur choisira l'alternative la plus proche.

Comprendre la syntaxe OKLCH

La fonction de couleur oklch() prend trois paramètres obligatoires et un paramètre optionnel :

  • L : la Luminosité définit la proximité de la couleur avec le blanc ou le noir, où 0% est du noir pur et 100% du blanc pur.
  • C : le Chroma représente la quantité de couleur appliquée. À la valeur minimum de 0, la couleur est proche du gris, tandis que les valeurs plus élevées sont associées à une couleur plus saturée. En théorie, la valeur du chroma est infinie, mais en pratique elle est rarement supérieure à 0.5
  • H : la Teinte (Hue) définit la couleur elle-même, et sa valeur va de 0 à 360. Dans le concept, H est similaire à un disque chromatique. Dans le modèle de couleur sRGB, 0 représente le rouge, mais dans le model Display P3, 0 est un rose profond.
  • alpha : cette valeur optionnelle représente l'opacité, elle va de 0 à 1.

Voici un exemple de couleur écrit avec la fonction oklch() :

  .color: {
    oklch(70% 0.3 150) /* Ça donnera un vert éclatant */
  }

  .color.alpha {
    color: oklch(70% 0.3 150 / 0.5) /* Ce vert aura de la transparence */
  }

La fonction oklch() est assez intuitive. On n'a besoin que de la quantité de luminosité, de l'intensité de l'ombre et de la couleur elle-même.

Comparaison de OKLCH avec d'autres fonctions de couleurs

Le modèle de couleur oklch est plus intuitif et plus cohérent que d'autres fonctions comme rgb(), hex, hsl() et lch(). Voyons ça de plus près.

OKLCH vs RGB et HEX

Les fonctions de couleur rbg() et hex utilisent la même approche, seule change la notation. Toutes deux créent une couleur de l'espace sRGB en modifiant trois valeurs : le rouge, le vert et le bleu. rgb() et hex sont probablement les deux fonctions les plus utilisées sur le web.

Voici un exemple de couleurs rgb() et hex :

.rgb-square{
  background-color: rgb(145, 230, 200);
}

.hex-square {
  background-color: #78f25b;
}

Pouvez-vous déterminer de quelles couleurs il s'agit rien qu'en lisant le code ?

Dans cet exemple, la couleur rgb() est dominée par le vert, puis le bleu, et un peu de rouge. Comme les valeurs sont assez élevées, la couleur qui en résultera aura une assez grande luminosité. Mais comment cette information se traduit-elle en une couleur compréhensible ? La couleur hex quant ) elle est encore plus difficile à traduire car elle demande de savoir lire les valeurs hexadécimales.

Avec ces modèles, il est donc difficile de déterminer une couleur à partir de sa formule, et de savoir quelles valeurs modifier pour arriver à la couleur ou à la nuance recherchée est un vrai défi.

Voici les mystérieuses couleurs de nos exemples précédents :

Colors Created RBG HEX Color Functions
Ces deux carrés ont été créés avec les fonctions de couleur rgb() et hex respectivement.

Regardons maintenant une couleur écrite avec la fonction oklch() :

.oklch-square {
  background-color: oklch(45% 0.2 200);
}

Cette couleur a une luminosité de 45%, nous pouvons donc supposer qu'elle n'est pas très brillante. La valeur de chroma est 0.2, elle est donc très saturée. Et la valeur 200 de la teinte correspond à la couleur turquoise, nous pouvons donc en déduire que la couleur est une variante légèrement sombre et atténuée de turquoise.

Voici la couleur :

Color Created OKLCH Color Function
Un carré créé avec la fonction de couleur oklch().

Avec cette fonction de couleur il est bien plus facile de déduire la couleur et de comprendre quelles valeurs modifier pour créer des variantes plus claires, plus sombres ou plus brillantes. C'est ici que les avantages de oklch() commencent à apparaître.

Comparons maintenant oklch() avec un autre modèle de couleur qui fonctionne sur le même principe, mais qui n'a pas la même cohérence.

OKLCH vs HSL

Avant le module de couleur 4, hsl() était la meilleure option pour créer intuitivement une palette de couleurs. Cette function a trois paramètres : la teinte (Hue), la saturation et la luminosité. On pourrait penser que saturation et chroma sont la même chose, mais en fait non ! La saturation renvoie à la force ou l'intensité d'une couleur, tandis que le chroma renvoie à la pureté de la couleur (combien de blanc, de noir ou de gris a été ajouté).

Comme le disent Andrey Sitnik et Travis Turner dans leur article OKLCH en CSS, pourquoi nous avons abandonné RGB et HSL, HSL est un espace de couleur distribué dans un cylindre. Ça signifie que si nous plaçons cet espace dans un graphe à deux dimensions, nous observerons que chaque couleur a la même saturation, de 0% à 100%. Mais ce n'est pas comme cela que nos yeux perçoivent la saturation. En réalité, chaque teinte a des valeurs de saturation différentes.

Remarquez la différence quand nous comparonsles espaces de couleur HSL et OKLCH et que nous supprimons la teinte :

Comparing HSL OKLCH Color Spaces
Comparaison des espaces de couleur HSL et OKLCH, avec les mêmes valeurs de chroma ou de saturation. Les illustrations du haut montrent commentla teinte est distribuée dans chaque espace ; les illustrations du bas montrent la même teinte mais en noir et blanc ; crédit image : OKLCH in CSS: Why we moved from RGB and HSL.

Vous remarquerez comment OKLCH présente une teinte plus uniforme que HSL. C'est ce qui affecte la cohérence de rendu de ce dernier lorsque nous commençons à manipuler les couleurs.

Pour mieux comprendre, prenons un exemple. nous allons créer deux boutons avec les modèles hsl() et oklch() en utilisant les valeurs suivantes :

  • Teinte : 90 pour le premier bouton et 270 pour le second.
  • Saturation : 100% pour hsl
  • Chroma : 0.5 pour oklch
  • Luminosité : 50%
  • Couleur du texte : blanc

Voici les boutons :

Buttons Created HSL OKLCH Color Models
Les boutons du haut ont été créés avec le modèle de couleur hsl() ; les boutons du bas ont été crées avec le modèle oklch().

On constate d'abord que les couleurs ne sont pas les mêmes, car les cercles chromatiques de HSL et OKLCH diffèrent. On remarque que les boutons créés avec hsl() n'offrent pas le même niveau de contraste ; le bouton vert est presque illisible ! Les boutons créés avec la fonction de couleur oklch() ont un niveau de luminosité perçue assez similaires, et offrent une expérience comparable en termes de lisibilité.

Le modèle hsl() n'est pas fiable lorsqu'il s'agit de manipuler et créer des palettes de couleurs. oklch() offre la même expérience intuitive que hsl(), mais avec des rendus plus cohérents.

OKLCH vs LCH

Le modèle de couleur lch() est très similaire à oklch() et offre généralement des résultats très cohérents. Un point d'attention toutefois, comme Andrey Sitnik et Travis Turner l'ont fait remarquer dans leur article : lch() a un bug qui affecte les valeurs de chroma et luminosité du bleu (c'est à dire les teintes lch() entre 270 et 330).

oklch() a été créé comme une version de lch() qui serait plus aisée à comprendre pour les devices et offirait des résultats plus cohérents. On y est parvenu en résolvant le bug en question, en améliorant la gamme de couleurs et en ajoutant quelques autres caractéristiques.

J'espère qu'il est clair que oklch() est intuitif, accessible et, d'une manière générale, qu'il représente la meilleure option pour créer des couleurs pour le web. Mettons cela en pratique.

Créer des palettes de couleurs avec OKLCH

Ah ! la partie amusante maintenant : nous allons utiliser oklch() pour créer quatre fenêtres d'alerte. Chacune aura une palette de couleurs différente pour communiquer un message spécifique. Voici une liste de palettes de couleurs et les messages associés :

  • palette "couleurs de la marque" : message produit
  • palette verte : message de succès
  • palette jaune : message d'avertissement
  • palette rouge : message d'erreur

Pouur chaque type de message (ou d'état), nous allons créer 9 nuances de la même couleur, depuis le très clair jusqu'au sombre. Nous associerons aussi une palette de couleur neutre pour le texte de la fenêtre et nous fournirons les modes lumineux et sombre.

Allons-y !

Créer une palette de couleur neutre

L'important quand on crée des couleurs neutres c'est d'avoir un chroma très faible. Le chroma définit la pureté de la couleur, donc une valeur proche de 0 résultera en une couleur proche du gris. Comme le noir pur (ou le blanc pur) peuvent fatiguer les yeux, nous ajoutons une teinte légère en utilisant une valeur de chroma de 0.01 .

Ensuite, nous définissons notre teinte de couleur de marque. Ça pourrait être n'importe quelle valeur, mais pour cet exemple j'ai choisi 280 parce que j'aime cette nuance particulière de bleu.

Maintenant nous allons commencer à modifier les valeurs de luminosité. L'important ici c'est de commencer avec une valeur assez élevée pour la première couleur et de la réduire petit à petit à une valeur relativement basse pour la dernière couleur.

J'ai commencé avec une valeur de luminosité de 97% et je termine avec 12%. Voici les propriétés custom auxquelles je suis arrivé :

:root {
  --clr-neutral-100: oklch(97% 0.01 280);
  --clr-neutral-200: oklch(89% 0.01 280);
  --clr-neutral-300: oklch(80% 0.01 280);
  --clr-neutral-400: oklch(71% 0.01 280);
  --clr-neutral-500: oklch(60% 0.01 280);
  --clr-neutral-600: oklch(49% 0.01 280);
  --clr-neutral-700: oklch(38% 0.01 280);
  --clr-neutral-800: oklch(25% 0.01 280);
  --clr-neutral-900: oklch(12% 0.01 280);
}

Et voici la palette de couleur neutre qui en résulte :

Neutral Color Palette OKLCH
Une palette de couleurs neutre, avec ses couleurs arrangées de la plus lumineuse à la plus sombre.

J'ai créé cette palette simplement en regardant les valeurs et le résultat est plutôt bon ! Il y a certainement des approches plus précises pour arriver à une transition plus douce entre les nuances, mais une des caractéristiques les plus remarquables de oklch() est qu'il permet de créer des palettes de couleurs de façon intuitive et avec des résultats assez cohérents.

Avant de créer les palettes de couleurs pour les différents états, jetons un œil au design de notre fenêtre, du point de vue de l'accessibilité.

Prendre en compte les considérations d'accessibilité

Pour ce qui est des couleurs, deux points d'accessibilité importants : assurer un contraste suffisant et fournir des façons alternatives (autres que la couleur) de faire passer une information.

Améliorer le contraste

Le critère de succès 1.4.3 - contraste minimum du WCAG 2.1 indique que le contraste minimal pour un texte normal ou grand est de 4.5:1 et 3:1 respectivement. Nous devrons choisir des combinaisons de couleurs permettant ces ratios de contraste. J'ai attendu, pour discuter de ce point, d'avoir déjà créé notre palette de couleur neutre, afin que nous puissions déjà l'utiliser pour faire un prototype.

Item Shade
Accent 700
Background 200
Text 800

Voici notre fenêtre de message :

Sample Message Window Neutral Color Palette
Fenêtre de message créée avec la palette de couleurs neutres.

Améliorer la communication

Le critère de succès 1.4.1 - utilisation de la couleur du WCAG 2.1 spécifie que la couleur ne devrait pas "être utilisée comme moyen de communiquer une information, d'indiquer une action, de demander une réponse, ou de distinguer un élément visuel". En nous conformant aux techniques suggérées par le WCAG nous avons clarifié l'information du contenu textuel lui-même et nous avons ajouté une icône facilement reconnaissable pour donner une indication supplémentaire sur son contenu :

Sample Message Window Improved Communication
Fenêtre de message avec une icône à gauche.

Nous avons avancé sur l'accessibilité, créons maintenant une palette de couleurs pour nos différents états.

Créer les palettes de couleurs d'états

Maintenant que nous avons une échelle de luminosité, le temps est venu de l'utiliser pour créer nos couleurs de marque. Pour ce faire, nous allons modifier les valeurs de chroma — mais comment savoir lesquelles utiliser ? Là encore, le mieux est de faire confiance à ses propres yeux, mais il y a quand même une méthode qui donne de bons résultats la plupart du temps. Mon approche consiste à modifier les valeurs de façon telle que les nuances les plus extrêmes (les valeurs 100 et 900) aient des valeurs de chroma faibles et les nuances moyennes (vers 500) des valeurs de chroma élevées. Si je devais représenter cela sur un graphique, ça donnerait ceci :

Chroma Values Color Shades
Graphe de valeurs de chroma pour différentes nuances de couleurs ; les nuances moyennes ont les valeurs de chroma les plus élevées.

Cela va créer un groupe de nuances allant du presque blanc au presque noir avec des couleurs plus vives au milieu. Nous devrons ajouter ces valeurs de chroma à nos propriétés custom.

Vous vous rappelez que nous avons sélectionné 280 comme la valeur de base de notre teinte (Hue) et nous l'utilisons pour notre palette de couleurs neutres. Maintenant nous allons copier les valeurs, les modifier, et les ajouter à de nouvelles propriétés custom :

:root {
  --clr-brand-100: oklch(97% 0.02 280);
  --clr-brand-200: oklch(89% 0.05 280);
  --clr-brand-300: oklch(80% 0.12 280);
  --clr-brand-400: oklch(71% 0.19 280);
  --clr-brand-500: oklch(60% 0.27 280);
  --clr-brand-600: oklch(49% 0.19 280);
  --clr-brand-700: oklch(38% 0.12 280);
  --clr-brand-800: oklch(25% 0.05 280);
  --clr-brand-900: oklch(12% 0.02 280);
}

Voici notre palette de couleurs de marque :

Brand Color Palette OKLCH
Palette de couleurs de marque, avec les couleurs allant du plus lumineux au plus sombre.

Et maintenant il est temps de créer les palettes de couleurs pour les messages de succès, avertissement et erreur. Tout ce que nous avons à faire, c'est de copier les valeurs de luminosité et de chroma utilisées pour nos couleurs de marque et de modifier les valeurs de teinte.

Le cercle chromatique d'OKLCH est un peu différent, donc je vais juste mettre les valeurs ici :

État Teinte
Succès 150
Avertissement 80
Erreur 20

Et voici nos nouvelles propriétés custom :

:root {
  --clr-success-100: oklch(97% 0.02 150);
  --clr-success-200: oklch(89% 0.05 150);
  --clr-success-300: oklch(80% 0.12 150);
  --clr-success-400: oklch(71% 0.19 150);
  --clr-success-500: oklch(60% 0.27 150);
  --clr-success-600: oklch(49% 0.19 150);
  --clr-success-700: oklch(38% 0.12 150);
  --clr-success-800: oklch(25% 0.05 150);
  --clr-success-900: oklch(12% 0.02 150);

  --clr-warning-100: oklch(97% 0.02 80);
  --clr-warning-200: oklch(89% 0.05 80);
  --clr-warning-300: oklch(80% 0.12 80);
  --clr-warning-400: oklch(71% 0.19 80);
  --clr-warning-500: oklch(60% 0.27 80);
  --clr-warning-600: oklch(49% 0.19 80);
  --clr-warning-700: oklch(38% 0.12 80);
  --clr-warning-800: oklch(25% 0.05 80);
  --clr-warning-900: oklch(12% 0.02 80);

  --clr-error-100: oklch(97% 0.02 20);
  --clr-error-200: oklch(89% 0.05 20);
  --clr-error-300: oklch(80% 0.12 20);
  --clr-error-400: oklch(71% 0.19 20);
  --clr-error-500: oklch(60% 0.27 20);
  --clr-error-600: oklch(49% 0.19 20);
  --clr-error-700: oklch(38% 0.12 20);
  --clr-error-800: oklch(25% 0.05 20);
  --clr-error-900: oklch(12% 0.02 20);
}

Et pour finir, voici nos palettes de couleurs pour les messages d'états :

Success Warning Error Message Color Palettes OKLCH
Palettes de couleurs pour succès (vert), avertissement (jaune), et erreur (rouge), les couleurs sont organisées de la plus lumineuse à la plus sombre; les couleurs utilisent les mêmes valeurs de luminosité.

Et voilà ! avec OKLCH, vous pouvez créer rapidement les couleurs dont vous avez besoin, juste en modifiant quelques valeurs, de façon cohérente et intuitive.

Maintenant, nous allons appliquer ces couleurs à notre composant message d'état, et nous allons les rendre compatibles avec les modes light et dark. Pour cela, nous utiliserons ces propriétés custom pour définir des variantes.

Gérer les différents états dans les fenêtres de messages

Pour ce projet, nous allons créer trois nuances : accent (pour les bordures de cartes et pour les boutons), background et texte. Nous les utiliserons partout, sauf pour l'icône et le texte du bouton primaire qui seront réalisés avec la palette de couleurs neutres.

Nous devons modifier deux nuances : 200 (background) et 700 (accents), et créer quelques propriétés custom pour chaque état.

Nous allons aussi créer quelques "valeurs atomiques de design' (design tokens).

Les design tokens sont des entités nommées qui représentent des valeurs de design atomiques. Ce sont des paires clé-valeur, dans lesquelles la clé est un nom qui représente une valeur primitive de couleur, d'espace, de taille de police, etc.

:root {
  /* Neutral color design tokens */
  --clr-text: var(--clr-neutral-800);
  --clr-text-invert: var(--clr-neutral-200);

  /* Non-neutral color design tokens */
  --clr-brand-accent: var(--clr-brand-700);
  --clr-brand-background: var(--clr-brand-200);
  --clr-success-accent: var(--clr-success-700);
  --clr-success-background: var(--clr-success-200);
  --clr-warning-accent: var(--clr-warning-700);
  --clr-warning-background: var(--clr-warning-200);
  --clr-error-accent: var(--clr-error-700);
  --clr-error-background: var(--clr-error-200);
}

Ici, nous définissons des design tokens plutôt que d'utiliser les couleurs directement, ce qui nous facilitera la vie lorsque nous créerons des variantes pour le mode sombre tout à l'heure.

Pour la simplicité, je n'ajoute ici que le style en lien avec la couleur. J'ajoute également la structure HTML utilisée pour les fenêtres :

<div class="card" data-type="brand"> <!-- This dataset will be used to define colors later -->
  <div class="card__icon-container">
    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
      <!-- SVG path -->
    </svg>
  </div>
  <div class="card__text-container">
    <h2>Welcome to FakeApp™</h2>
    <p>This is an app that doesn't exist at all!</p>
    <p>We invite you to check what that app offers by using our tour functionality.</p>
    <div class="button__container">
      <button class="button__primary">Start tour</button>
      <button class="button__secondary">Omit</button>
    </div>
  </div>
</div>
.card {
  border: 5px solid var(--window-accent);
  background-color: var(--window-background);
}

.card__icon-container {
  background-color: var(--window-accent);
  color: var(--clr-text-invert);
}

.card__icon-container svg {
  stroke: currentColor;
}

.card h2 {
  color: var(--window-accent);
}

.button__primary {
  background-color: var(--window-accent);
  color: var(--clr-text-invert);
  border-color: transparent;
}

.button__secondary {
  background-color: transparent;
  color: var(--window-accent);
  border-color: currentColor;
}

Comme vous le voyez, j'ai créé deux variables pour chaque fenêtre : --window-accent et --window-background. J'utiliserai un attribut data- pour définir les propriétés custom de la fenêtre, grâce à nos design tokens :

.card[data-type="brand"] {
  --card-accent: var(--clr-brand-accent);
  --card-background: var(--clr-brand-background);
}

.card[data-type="success"] {
  --card-accent: var(--clr-success-accent);
  --card-background: var(--clr-success-background);
}

.card[data-type="warning"] {
  --card-accent: var(--clr-warning-accent);
  --card-background: var(--clr-warning-background);
}

.card[data-type="error"] {
  --card-accent: var(--clr-error-accent);
  --card-background: var(--clr-error-background);
}

Voici le résultat :

Message Windows Custom Color Palettes OKLCH
Fenêtres de message utilisant les palettes bleu (pour la marque), vert (succès), jaune (alerte) et rouge (erreur).

Nous avons vu à quel point il est facile de créer des variantes de couleurs à l'aide de design tokens, mais qu'en est-il du contraste ? Avec le modèle oklch(), si nous gardons les mêmes valeurs de luminosité sur l'ensemble des palettes, le contraste restera inchangé ou très proche. Pour le démontrer, voici une comparaison entre le contraste de la fenêtre de marque (couleurs neutres) et celle de la fenêtre d'erreur.

Contrast Comparison Neutral Warning Message Windows
Comparaison des fenêtres "marque" (palette de couleurs neutres) et "erreur" (palette de couleurs rouges). Le contraste entre le titre (shade 700) et l'arrière-plan (shade 200) est de 7.2 pour la première et 7.5 pour la seconde.

Modifier les valeurs de chroma en revanche pourrait avoir un impact sur le constraste, mais à moins de créer une palette de couleurs vraiment saturées, on ne devrait pas avoir de problème. À présent, la seule chose qu'il nous reste à faire est de créer des versions pour le mode sombre.

Créer des variantes pour le mode sombre

Nous pouvons ajouter les variantes "dark-mode" à nos design-tokens dans la media query CSS prefers-color-scheme pour créer les variantes respectives lorsque l'utilisateur a activé le mode sombre dans son système ou son navigateur.

@media screen and (prefers-color-scheme: dark) {
  :root {
    --clr-background: var(--clr-neutral-900);
    --clr-text: var(--clr-neutral-200);
    --clr-text-invert: var(--clr-neutral-900);
    --clr-brand-accent: var(--clr-brand-300);
    --clr-brand-background: var(--clr-brand-800);
    --clr-success-accent: var(--clr-success-300);
    --clr-success-background: var(--clr-success-800);
    --clr-warning-accent: var(--clr-warning-300);
    --clr-warning-background: var(--clr-warning-800);
    --clr-error-accent: var(--clr-error-300);
    --clr-error-background: var(--clr-error-800);
  }
}

Voici comment nos fenêtres s'afficheront en mode sombre :

Message Windows OKLCH Color Palettes Dark Mode
Messages de marque, succès, alerte, et erreur réalisées avec les palettes "inversées" du mode sombre.

Et voilà ! Vous pouvez utiliser la fonction de couleur oklch() pour créer une palette de couleurs qui produit des résultats cohérents.

Compatibilité navigateurs

Selon CanIUse, la fonction oklch() est compatible avec les principaux navigateurs. Cela dit, Firefox l'a mis en œuvre en juin 2023 et Samsung Internet n'est toujours pas compatible à la date de rédaction de cet article. On ne peut pas non plus supposer que tous les utilsateurs ont la dernière version de leur navigateur, par conséquent il est utile de créer une solution de repli si l'on souhaite utiliser ce modèle de couleur en production.

Un outil peut nous y aider : l'excellent site Huetone nous permet de créer facilement une palette de couleurs avec oklch et de l'exporter en format hexadécimal, prêt à l'usage en CSS. Nous pouvons même copier la palette sous forme de design tokens et l'utiliser dans Figma avec le plugin Design Tokens

Cet article n'est pas un tutoriel Huetone, d'autant que ce n'est pas nécessaire ! Le mode d'emploi est très clair. Voici les design-tokens que j'ai créés sur Huetone.

Prenez soin de bien nommer vos couleurs. Personnellement j'ai suivi cette convention de nommage pour mes propriétés custom : --clr-[etat]-[nuance].

N.B. : si la couleur créée par oklch n'est pas supportée par l'espace sRGB, Huetone choisira l'option la plus proche. Ce ne sera pas une réplique exacte, en particulier pour les couleurs qui ont une valeur de chroma élevée, mais ce sera suffisant pour offrir une bonne expérience, et surtout, cela conservera le ratio de contraste et l'accessibilité ne sera pas affectée.

Créer une solution de repli

Maintenant que nous avons nos couleurs alternatives, nous avons besoin de les ajouter comme solution de repli. C'est ici que la feature query @supports entre en jeu. Nous l'utilisons pour détecter si le navigateur supporte cette fonctionnalité, et sinon nous lui disons d'utiliser notre solution de repli.

La syntaxe de @supports est très simple, nous avons juste besoin d'ajouter entre parenthèses les propriétés que nous voulons détecter. Dans le cas présent, nous voulons détecter si oklch() n'est pas supporté, c'est pourquoi nous plaçons un préfixe not avant la prenthèse :

@supports not (background-color: oklch(0%, 0, 0)) {
  :root {
    --clr-neutral-100: #f3f4fc;
    --clr-neutral-200: #d9dae1;
    --clr-neutral-300: #bcbdc4;
    --clr-neutral-400: #a0a1a8;
    --clr-neutral-500: #7f8086;
    --clr-neutral-600: #5f6066;
    --clr-neutral-700: #414248;
    --clr-neutral-800: #212126;
    --clr-neutral-900: #050509;

    --clr-brand-100: #f3f4ff;
    --clr-brand-200: #d4d8fa;
    --clr-brand-300: #b0b7ff;
    --clr-brand-400: #9094ff;
    --clr-brand-500: #6d64ff;
    --clr-brand-600: #5147c9;
    --clr-brand-700: #383681;
    --clr-brand-800: #1d1e3a;
    --clr-brand-900: #05050e;

    --clr-success-100: #edf9ef;
    --clr-success-200: #c6e4cb;
    --clr-success-300: #83d494;
    --clr-success-400: #1dc15d;
    --clr-success-500: #009a46;
    --clr-success-600: #007433;
    --clr-success-700: #005121;
    --clr-success-800: #0b2813;
    --clr-success-900: #020703;

    --clr-warning-100: #fdf4e7;
    --clr-warning-200: #edd8b6;
    --clr-warning-300: #e5b562;
    --clr-warning-400: #d19500;
    --clr-warning-500: #a67600;
    --clr-warning-600: #7e5900;
    --clr-warning-700: #583d00;
    --clr-warning-800: #2e1e00;
    --clr-warning-900: #0a0500;

    --clr-error-100: #fff2f1;
    --clr-error-200: #fccecc;
    --clr-error-300: #ff9f9f;
    --clr-error-400: #ff6970;
    --clr-error-500: #ee003f;
    --clr-error-600: #b31030;
    --clr-error-700: #742028;
    --clr-error-800: #371617;
    --clr-error-900: #0c0303;
  }
}

Vous pouvez jeter un coup d'œil au projet, avec sa solution de repli, dans ce codepen :

voir Message windows with oklch() de Cristian Diaz dans CodePen

Conclusion

CSS est en constante évolution. Le modèle de couleur oklch() nous permet d'utiliser la plus grande variété de couleurs disponible dans l'espace de couleur Display P3. Son utilisation est intuitive et, contrairement à la plupart des fonctions de couleurs précédentes, il offre des résultats cohérents.

Autres ressources externes

Articles de Cristian Diaz traduits dans La Cascade

Voir la page de Cristian Diaz et la liste de ses articles dans La Cascade.
Article original paru le 10 août 2023 dans le blog de LogRocket
Traduit avec l'aimable autorisation du blog de LogRocket et de Cristian Diaz.
Copyright le blog de LogRocket © 2023