Utilisez OKLCH lorsque ses coordonnées correspondent au travail de palette
OKLCH est la forme polaire d’Oklab. L représente la luminosité perceptuelle, C la chroma et H un angle de teinte. CSS Color 4 décrit Oklab comme optimisé pour les couleurs visuellement proches et relève des progrès de linéarité de teinte, d’uniformité perceptuelle et de prédiction de chroma par rapport à CIE LCH. OKLCH convient donc pour organiser des jetons apparentés, notamment des gammes de luminosité ou des interpolations qui s’affadissent moins facilement que certains mélanges rectangulaires. Le modèle est amélioré, pas parfait : chaque étape exige une revue visuelle sur de vrais écrans.
- Utilisez L pour organiser les rôles clairs et sombres, en sachant que des pas numériques égaux n’approximent que des pas visuels égaux.
- Utilisez C pour contrôler la distance à l’axe neutre ; une valeur supérieure est plus colorée jusqu’à la limite du gamut de sortie.
- Utilisez H pour maintenir une famille près d’une teinte ou choisir un trajet explicite entre teintes.
- Considérez L, C et H comme des coordonnées de palette, non comme des affirmations d’accessibilité. WCAG utilise la luminance relative des couleurs sRGB finalement rendues.
- Consignez le gamut visé et le repli avec la source OKLCH afin de reproduire le jeton entre navigateurs, outils et écrans.
Écrivez la syntaxe sans tomber dans le piège du pourcentage de chroma
La syntaxe moderne emploie des espaces et une barre facultative avant alpha : oklch(L C H / A). Les virgules sont invalides. La luminosité accepte un nombre de 0 à 1 ou un pourcentage de 0% à 100%. La chroma s’écrit généralement comme un nombre ; CSS Color 4 définit 100% de chroma comme 0,4, donc 25% signifie 0,1 et non 0,25. Il n’existe pas de maximum universel : environ 0,5 couvre la plage pratique, mais la limite utile dépend de L, H et du gamut. Une chroma négative est ramenée à zéro.
:root {
--brand: oklch(70% 0.16 30);
--brand-same-chroma: oklch(70% 40% 30); /* 40% of 0.4 = 0.16 */
--brand-muted: oklch(70% 0.08 30);
--brand-overlay: oklch(70% 0.16 30 / 65%);
}| Coordonnée | Forme CSS | Sens pratique | Limite importante |
|---|---|---|---|
| L | 70% ou 0.7 | Coordonnée de luminosité perceptuelle | Pas la luminance relative WCAG |
| C | 0.16 ou 40% | Distance à l’axe neutre | 100% correspond à 0.4 |
| H | 30 ou 30deg | Angle polaire de teinte | Sans effet quand la chroma est presque nulle |
| A | / 65% | Opacité avant composition | Le contraste dépend du fond |
Construisez une gamme de luminosité et testez chaque premier plan
La gamme suivante maintient C à 0,08 et H à 30 tandis que L passe de 35% à 85%. Les valeurs HEX sont des approximations sRGB 8 bits calculées avec les matrices Oklab de CSS Color 4 et arrondies au canal le plus proche. Le contraste est ensuite recalculé depuis chaque HEX selon la formule WCAG. AA exige 4,5:1 pour le texte normal. Cette séparation est essentielle : L structure la gamme, mais la couleur finale composée fournit la preuve d’accessibilité.
| OKLCH | sRGB 8 bits | Texte noir | Texte blanc | Choix AA normal |
|---|---|---|---|---|
| oklch(35% 0.08 30) | #5D2820 | 1.79:1 | 11.73:1 | Blanc |
| oklch(45% 0.08 30) | #7C433A | 2.72:1 | 7.72:1 | Blanc |
| oklch(55% 0.08 30) | #9B5F55 | 4.16:1 | 5.05:1 | Blanc |
| oklch(65% 0.08 30) | #BB7D72 | 6.29:1 | 3.34:1 | Noir |
| oklch(75% 0.08 30) | #DC9B90 | 9.13:1 | 2.30:1 | Noir |
| oklch(85% 0.08 30) | #FEBBAF | 12.94:1 | 1.62:1 | Noir |
- Pour cette teinte et cette chroma, le premier plan bascule entre L 55% et L 65% ; il n’existe pas de seuil universel de luminosité OKLCH.
- L 55% ne permet pas au noir de satisfaire AA pour le texte normal, même au milieu apparent de la gamme : le rapport vaut 4,16:1.
- Conservez les rapports non arrondis pour décider et n’arrondissez que la documentation affichée.
- Testez hover, selected, disabled, dégradés et transparences après composition de toutes les couches.
- Un HEX approximatif aide à revoir sRGB, mais ne peut pas coder exactement une couleur source hors sRGB.
Augmentez la chroma jusqu’à rencontrer la limite du gamut cible
Aucun maximum de chroma n’est sûr pour toutes les palettes. À L 70% et H 30, les valeurs jusqu’à C 0,19 restent dans sRGB pour ce calcul. C 0,20 est déjà hors sRGB mais dans Display P3, et C 0,24 demeure une couleur OKLCH valide contenue par ce gamut plus large. Une autre luminosité ou teinte atteint sa limite ailleurs. Hors sRGB, aucun HEX 8 bits exact n’existe ; le remplacer par un HEX écrêté masquerait le changement de gamut et pourrait modifier teinte ou luminosité.
| OKLCH à L 70%, H 30 | Approximation sRGB 8 bits | sRGB | Display P3 | Interprétation |
|---|---|---|---|---|
| C 0.00 | #9E9E9E | Dedans | Dedans | Neutre ; teinte sans effet |
| C 0.08 | #CB8C81 | Dedans | Dedans | Couleur atténuée |
| C 0.16 | #F17260 | Dedans | Dedans | Couleur sRGB forte |
| C 0.19 | #FE6652 | Dedans | Dedans | Près de cette limite sRGB |
| C 0.20 | — | Dehors | Dedans | Aucune représentation HEX exacte |
| C 0.24 | — | Dehors | Dedans | Résultat à gamut étendu |
Séparez le repli syntaxique du gamut mapping
Le repli et le gamut mapping résolvent deux problèmes distincts. Le repli fournit à un ancien logiciel une déclaration comprise. Un navigateur compatible peut analyser OKLCH mais devoir encore adapter la couleur au gamut réel de l’écran. Utilisez @supports lorsqu’une propriété personnalisée doit rester valide dans son ensemble : y placer seulement une couleur non prise en charge peut laisser la déclaration valide jusqu’à la substitution, puis faire échouer la propriété consommatrice au lieu d’utiliser une valeur antérieure. Le bloc conditionnel évite ce piège.
:root {
--brand: #FE6652;
}
@supports (color: oklch(70% 0.20 30)) {
:root {
--brand: oklch(70% 0.20 30);
}
}
.button {
color: #000000;
background: var(--brand);
}- Choisissez délibérément le repli ; #FE6652 est la dernière étape sRGB de l’exemple, pas une identité avec C 0,20.
- Précisez si le jeton préféré vise sRGB, Display P3 ou un autre gamut et testez les écrans représentant chaque voie.
- N’écrêtez pas préalablement tous les jetons pour faire concorder les outils : vous perdriez la source étendue et pourriez créer des gammes irrégulières.
- Attendez du navigateur ou du pipeline qu’il fasse le gamut mapping à la sortie ; inspectez le rendu au lieu de supposer un algorithme immuable.
- Recalculez le contraste du repli et de la couleur préférée adaptée, sans hériter d’un rapport unique des coordonnées source.
Choisissez délibérément l’espace d’interpolation et le trajet de teinte
L’espace entre les extrémités compte autant que leur notation. Les dégradés CSS et color-mix() peuvent demander une interpolation OKLCH. Un espace polaire peut mieux préserver la chroma qu’un mélange rectangulaire traversant un milieu terne, mais plusieurs trajets existent autour du cercle de teinte. Les trajets court et long produisent des familles intermédiaires très différentes ; increasing et decreasing fixent le sens. Des intermédiaires peuvent aussi sortir du gamut même si les deux extrémités s’affichent, donc la gamme finale exige toujours des contrôles de gamut et de contraste.
.spectrum {
background: linear-gradient(
90deg in oklch shorter hue,
oklch(70% 0.16 30),
oklch(70% 0.16 280)
);
}
:root {
--brand-soft: color-mix(
in oklch,
oklch(70% 0.16 30) 35%,
white
);
}- Utilisez Oklab pour une interpolation perceptuelle droite et OKLCH lorsque le trajet polaire ou la préservation de chroma compte davantage.
- Précisez shorter, longer, increasing ou decreasing hue si le trajet change le sens produit ; ne dépendez pas d’une valeur implicite accidentelle.
- Échantillonnez les étapes intermédiaires : les extrémités seules ne révèlent pas un milieu hors gamut ou à faible contraste.
- Le mélange avec le blanc change plus que L dans un modèle polaire. Si une seule coordonnée doit varier, générez des jetons OKLCH explicites.
- Conservez les couleurs dérivées dans le même pipeline documenté afin que maquettes, CSS, captures et audits suivent les mêmes règles.
Livrez les jetons OKLCH avec des preuves auditables
Une palette OKLCH de production doit pouvoir être révisée sans reconstruire les décisions cachées d’un outil de design. Stockez les coordonnées source avec une précision utile, identifiez le gamut cible, gardez un repli intentionnel et exportez les preuves calculées avec chaque jeton sémantique. Testez ensuite les états réellement rendus. Les avantages perceptuels sont ainsi conservés, tandis que support navigateur, gamut et accessibilité deviennent des données d’ingénierie ordinaires.
:root {
--action-strong: oklch(55% 0.08 30);
--action: oklch(65% 0.08 30);
--action-soft: oklch(85% 0.08 30);
--on-action-strong: #FFFFFF; /* 5.05:1 on #9B5F55 */
--on-action: #000000; /* 6.29:1 on #BB7D72 */
--on-action-soft: #000000; /* 12.94:1 on #FEBBAF */
}- Distinguez L de la luminance relative WCAG et C de la saturation HSL.
- Documentez la normalisation des pourcentages, notamment que C 100% vaut 0,4 en CSS.
- Considérez la teinte comme sans effet pour les neutres et évitez les libellés instables fondés sur une coordonnée invisible.
- Consignez les jetons dans sRGB, ceux qui exigent un gamut étendu et le repli servi lorsque la voie préférée est indisponible.
- Gardez assez de précision pour convertir, mais publiez un HEX arrondi uniquement comme approximation sRGB 8 bits identifiée.
- Testez le contraste des couleurs finales composées ; alpha, dégradés, superpositions et gamut mapping peuvent changer la paire visible.
- Révisez séparément les milieux d’interpolation, focus, bordures, hover, selected, thèmes clair et sombre et forced colors.
- Liez la spécification source et la méthode de conversion pour reproduire et expliquer les évolutions futures.
Sources primaires
Les affirmations factuelles de cet article sont vérifiées dans ces spécifications publiées.
- W3C CSS Color 4 — présentation d’Oklab et OkLCh
- W3C CSS Color 4 — spécification d’Oklab et OkLCh
- W3C CSS Color 4 — adaptation au gamut
- W3C CSS Color 4 — méthodes d’interpolation des couleurs
- W3C CSS Images 4 — interpolation des couleurs de dégradé
- W3C CSS Color 5 — color-mix()
- W3C CSS Conditional 3 — @supports
- W3C WCAG 2.2 — luminance relative
- W3C WCAG 2.2 — Contraste (minimum)