Écrêtage du gamut : pourquoi vos couleurs sont écrasées
Générez une rampe de bleu en dix étapes, poussez le chroma pour que la couleur de marque rayonne, puis livrez. Ce que l’écran renvoie est subtilement faux : la teinte la plus pâle a dérivé vers le cyan, les étapes les plus foncées se sont effondrées en quasi-doublons, et le bleu le plus profond tire vers le violet. Personne n’a fait de faute de frappe. Plusieurs des couleurs demandées ne peuvent tout simplement pas être produites sur un écran sRGB, et la conversion qui les a ramenées dans les limites les a écrasées.
L’écrêtage du gamut, c’est ce qui se produit quand une couleur existe dans votre modèle de couleur mais pas sur l’affichage : la valeur est forcée à l’intérieur du gamut de l’écran, et la méthode brute par défaut — plafonner chaque canal RGB indépendamment — décale la teinte et la luminosité en même temps que le chroma, transformant la couleur en une couleur différente plutôt qu’en une version plus discrète. Il existe deux remèdes : un mappage de gamut correct lorsqu’une couleur hors limites doit être convertie, et la génération de palettes avec une marge de sécurité pour qu’aucune étape ne quitte le gamut dès le départ. Les deux sont plus faciles à voir en OKLCH — cet article fait partie de notre guide OKLCH, où le modèle lui-même est présenté.
Que signifie « hors gamut » ?
Un modèle de couleur est un système d’adressage, et des adresses peuvent ne pointer vers rien. OKLCH accepte une luminosité de 0,65, un chroma de 0,25, une teinte de 262,9 sans broncher — une coordonnée bien formée qu’aucun écran sRGB ne peut afficher. Le gamut est l’ensemble des couleurs qu’un appareil ou un espace colorimétrique peut réellement reproduire, et c’est un volume fini et irrégulier situé à l’intérieur de l’espace de coordonnées beaucoup plus vaste du modèle.
La frontière est plus facile à se représenter comme un plafond de chroma qui
dépend de la luminosité. Près du blanc et près du noir, il n’y a presque pas de
place pour la coloration ; le plafond culmine dans les tons moyens. À la teinte
262,9 — la teinte du bleu #2563eb, soit oklch(0.546 0.215 262.9) — le plafond
sRGB se présente ainsi :
| Luminosité | Chroma sRGB max à la teinte 262,9 |
|---|---|
| 0,95 | ≈0,024 |
| 0,85 | ≈0,074 |
| 0,70 | ≈0,157 |
| 0,55 | ≈0,250 |
| 0,40 | ≈0,200 |
| 0,25 | ≈0,125 |
Une tente, pas un mur : haute au milieu, pincée aux deux extrémités. Toute demande au-dessus de cette toile est hors gamut, et quelque chose doit céder.
Que fait un plafonnement naïf à une couleur ?
La conversion bon marché plafonne chaque canal RGB à son maximum. Demandez
oklch(0.65 0.25 262.9) et le calcul produit un canal bleu linéaire à ≈1,36 —
36 % au-delà de ce que l’écran possède. Plafonnez chaque canal dans les limites
et vous obtenez #3480ff, qui se relit comme ≈ oklch(0.622 0.204 260.4).
Comparez la demande et le résultat : la luminosité a chuté de ≈0,028, le chroma de ≈0,046, et la teinte a pivoté de ≈2,5° vers le cyan. Seul le chroma était en excès, pourtant les trois axes ont bougé — parce que le plafonnement opère canal par canal en RGB, sans aucune notion de ce que les trois canaux signifient ensemble.
Un mappage de gamut correct, lui, possède cette notion : maintenez la luminosité
et la teinte, et réduisez le chroma jusqu’à ce que la couleur repasse à
l’intérieur de la frontière. La même demande se mappe vers
oklch(0.65 ≈0.186 262.9) — environ #4f89ff — une version visiblement plus
discrète du même bleu.
La raison perceptuelle pour laquelle la différence compte : l’œil tend à
pardonner « moins coloré » — il lit la même couleur, atténuée — mais un décalage
de teinte se lit comme une couleur différente. Le chroma, c’est le volume ; la
teinte, c’est l’identité. Le plafonnement naïf sacrifie l’identité pour préserver
le volume, et il devient d’autant plus violent que la demande est éloignée.
Demandez une teinte bleue proche du blanc à un chroma de 0,22 (le plafond y est
de ≈0,024) et le plafonnement aboutit à #9ee9ff — une teinte de ≈218, à 45°
complets. La teinte bleue est livrée en cyan.
Pourquoi les rampes s’aplatissent-elles au lieu de simplement s’atténuer ?
Une seule couleur écrasée est un défaut ponctuel. Les palettes échouent de façon plus systématique, car une rampe demande du chroma sur de nombreuses luminosités alors que le plafond varie en dessous. Partout où la demande dépasse, chaque étape en excès est plaquée contre la même frontière — et des étapes conçues pour différer arrivent presque identiques.
Des chiffres de l’extrémité foncée d’une rampe de bleu demandée à un chroma constant de 0,28, avec des étapes espacées de 0,05 en luminosité :
| Demandé | Après plafonnement canal par canal | Écart avec l’étape précédente |
|---|---|---|
oklch(0.40 0.28 262.9) | ≈ oklch(0.402 0.278 264.1) | — |
oklch(0.35 0.28 262.9) | ≈ oklch(0.377 0.261 264.1) | ≈0,025 |
oklch(0.30 0.28 262.9) | ≈ oklch(0.355 0.241 266.1) | ≈0,022 |
oklch(0.25 0.28 262.9) | ≈ oklch(0.334 0.221 269.0) | ≈0,021 |
L’espacement demandé était de 0,05 en luminosité ; l’espacement livré est de ≈0,021–0,025 — moins de la moitié, et juste à la limite d’une différence tout juste perceptible. Autour de 0,02 L, c’est à peu près là où deux échantillons adjacents cessent de se lire comme nettement distincts, ce qui explique pourquoi Scale Composer déclenche un avertissement dès que deux étapes voisines se retrouvent plus proches que cela. Remarquez aussi la colonne de teinte qui dérive de ≈264 à ≈269 : la bande aplatie n’est même pas un bleu cohérent.
Voilà la bande morte de l’introduction — pas un bug de rendu, juste plusieurs étapes partageant une même barrière.
Comment générer une palette qui ne s’écrête jamais ?
En traitant le plafond comme une donnée d’entrée plutôt que comme un accident. La solution côté génération, c’est la marge de sécurité : à chaque luminosité, plafonnez le chroma demandé légèrement en dessous du plafond du gamut, pour qu’aucune étape n’ait jamais besoin d’être plafonnée.
C’est ainsi que Scale Composer construit nativement ses échelles : les étapes sont placées sur une courbe de luminosité, le chroma suit un profil en cloche avec un plancher — généreux dans les tons moyens où le plafond est haut, s’amincissant vers les extrémités où il est bas — et le profil est plafonné juste en dessous du plafond à la luminosité de chaque étape. Le milieu éclatant reste éclatant, les extrémités pâles et foncées conservent leur identité, et chaque valeur produite était réalisable depuis le début.
Ouvrez la vue du plafond dans Scale Composer — la même couleur de départ bleue, avec le chroma de chaque étape se maintenant juste en dessous du plafond sRGB tandis qu’il monte et descend le long de la rampe. Faites glisser le chroma vers le haut et vous verrez quelles étapes s’écrêteraient en premier.

Display-P3 corrige-t-il l’écrêtage du gamut ?
Il déplace la barrière ; il ne la supprime pas. Display-P3 — le gamut plus large de la plupart des téléphones et Mac actuels — relève le plafond de chroma surtout là où la couleur vit déjà : à la teinte 262,9, le gain n’est que de ≈0,003 près du blanc mais de ≈0,05 autour d’une luminosité de 0,45–0,50 (de ≈0,225 jusqu’à ≈0,276). Les étapes de tons moyens qui étaient plaquées contre le plafond sRGB obtiennent une vraie marge pour respirer.
La discipline reste la même, cependant : le P3 a son propre plafond, et une
demande qui le dépasse s’écrête tout aussi mal. Générer avec une marge de
sécurité contre la frontière du P3, c’est le même algorithme sous une toile plus
haute. Dans le mode P3 de Scale Composer, chaque étape porte une chaîne
color(display-p3 …) pour les écrans capables de l’utiliser, tandis que la
colonne hex reste plafonnée en sRGB — repli et amélioration produits par une
seule échelle plutôt que maintenus à la main.
Voyez le soulagement là où il se produit
Basculez la même rampe de bleu en mode P3 et observez les étapes de tons moyens absorber la nouvelle marge de sécurité : le chroma monte exactement là où la barrière sRGB appuyait auparavant, la luminosité et la teinte restent immobiles, et les extrémités pâles bougent à peine. Une fois que vous avez vu le plafond comme une courbe — quelque chose sous quoi une palette glisse plutôt que ce contre quoi elle s’écrase — l’écrêtage du gamut cesse d’être un mystérieux bug de rendu et redevient ce qu’il a toujours été : une demande que l’écran ne pouvait jamais honorer, interceptée au moment de la génération plutôt que découverte le jour de la livraison.