You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This GitHub issue is for collecting web developer signals for Gamut mapping.
Colors in CSS and <canvas> elements can be defined out of range of an output device or the color space of the canvas. Gamut mapping brings the color into range while preserving hue and lightness.
Browser support
Chrome: not supported
Chrome Android: not supported
Edge: not supported
Firefox: not supported
Firefox for Android: not supported
Safari: not supported
Safari on iOS: not supported
Give us feedback
If you're pressed for time, but you want this feature to be available in all browsers, please give this issue a thumbs up 👍 reaction.
However, a much better guide for us is to know how you'd use this feature, and what you're having to do in the meantime. This helps us judge the priority versus other features.
Copy the template below in a comment, and add the details that matter to you.
## What I want to do with this feature<!-- Add your specific use-cases, even if they seem obvious to you. -->## What I'm having to do in the meantime<!--Are you having to use another feature instead, a polyfill, or is it blocking you completely?Why are the alternatives worse than using this feature?-->
Create dynamic color scales from a single accent color
What I'm having to do in the meantime
Hardcode all tints
More details
CSS currently provides several ways to define and manipulate colors, that are independent of any particular RGB gamut, such as oklch() or lab().
While this makes it easier to define and manipulate colors in ways that are closer to human perception, it also makes it much easier to define colors that fall outside of the display gamut of any output device, especially when modifying existing colors (that are in gamut to begin with!), such as when creating color ramps from a dynamic accent color.
For example, pick any non-neutral accent color (e.g. #0075ff, Chrome’s default AccentColor value), and adjust its OKLCh lightness to 97% to produce a tinted background color. The result (oklch(from #0075ff 97% c h) or oklch(0.97 0.2235 258.41)) is outside the display gamut of any conceivable display device. Without gamut mapping (i.e. currently in most UAs), this is displayed via converting to RGB, and clipping red, green, blue coordinates. This produces colors dramatically different than the specified color, losing all guarantees that these color spaces were supposed to provide.
This carries accessibility implications as well, since RGB clipping can significantly affect contrast characteristics, making color pairs inaccessible. See here a particularly egregious example where white is displayed as blue in non-GM browsers (bsky post).
To display these colors correctly they need to be mapped to the closest in-gamut color, typically by reducing chroma (≈ saturation) while preserving hue and lightness. Here is a visual of the example above, with each color as a dot shown relative to the P3 gamut:
Notice how the gamut shrinks dramatically as we get towards white (100%) or black (0%), so a color that was perfectly in-gamut for midtones, can be wildly out of gamut for lighter tints. We promised authors that color spaces like oklch() + relative colors would let them create dynamic color ramps, but that promise was never realized due to the lack of GM.
I wanted to build a theme editor from two hue inputs, for my CSS library candy.css, that would output a full OKLCH color palette for UI
I also wanted to use the OKLCH colors directly in my CSS to make defining my website's theme more logical (again, focusing more on hue and possibly allowing a theme selector later) back in 2024.
What I'm having to do in the meantime
I abandoned that approach entirely, and just made direct CSS color text fields for each color (a huge DX downgrade)
I actually got all the way to a production release before realizing that the gamut mapping was both inconsistent between browsers AND even inconsistent within parts of the same browser. As I recall, scrollbar-color actually performed different gamut mapping than background-image with linear-gradient, which really puzzled me for a long time. The next step I took was an obnoxious build system that converted OKLCH colors in JS to hex codes, so that the gamut mapping would be done correctly. As of 2026 I ended up moving to Google's HCT system with their Material 3 color palette library instead.
Activity
LeaVerou commentedon Oct 15, 2026
What I want to do with this feature
Create dynamic color scales from a single accent color
What I'm having to do in the meantime
Hardcode all tints
More details
CSS currently provides several ways to define and manipulate colors, that are independent of any particular RGB gamut, such as
oklch()orlab().While this makes it easier to define and manipulate colors in ways that are closer to human perception, it also makes it much easier to define colors that fall outside of the display gamut of any output device, especially when modifying existing colors (that are in gamut to begin with!), such as when creating color ramps from a dynamic accent color.
For example, pick any non-neutral accent color (e.g.
#0075ff, Chrome’s defaultAccentColorvalue), and adjust its OKLCh lightness to 97% to produce a tinted background color. The result (oklch(from #0075ff 97% c h)oroklch(0.97 0.2235 258.41)) is outside the display gamut of any conceivable display device. Without gamut mapping (i.e. currently in most UAs), this is displayed via converting to RGB, and clipping red, green, blue coordinates. This produces colors dramatically different than the specified color, losing all guarantees that these color spaces were supposed to provide.This carries accessibility implications as well, since RGB clipping can significantly affect contrast characteristics, making color pairs inaccessible. See here a particularly egregious example where white is displayed as blue in non-GM browsers (bsky post).
To display these colors correctly they need to be mapped to the closest in-gamut color, typically by reducing chroma (≈ saturation) while preserving hue and lightness. Here is a visual of the example above, with each color as a dot shown relative to the P3 gamut:
#0075ffoklch(from #0075ff 97% c h)oklch(from #0075ff 97% c h), gamut mapped to P3Notice how the gamut shrinks dramatically as we get towards white (100%) or black (0%), so a color that was perfectly in-gamut for midtones, can be wildly out of gamut for lighter tints. We promised authors that color spaces like
oklch()+ relative colors would let them create dynamic color ramps, but that promise was never realized due to the lack of GM.wavebeem commentedon Oct 15, 2026
What I want to do with this feature
I wanted to build a theme editor from two hue inputs, for my CSS library candy.css, that would output a full OKLCH color palette for UI
I also wanted to use the OKLCH colors directly in my CSS to make defining my website's theme more logical (again, focusing more on hue and possibly allowing a theme selector later) back in 2024.
What I'm having to do in the meantime
I abandoned that approach entirely, and just made direct CSS color text fields for each color (a huge DX downgrade)
I actually got all the way to a production release before realizing that the gamut mapping was both inconsistent between browsers AND even inconsistent within parts of the same browser. As I recall,
scrollbar-coloractually performed different gamut mapping thanbackground-imagewithlinear-gradient, which really puzzled me for a long time. The next step I took was an obnoxious build system that converted OKLCH colors in JS to hex codes, so that the gamut mapping would be done correctly. As of 2026 I ended up moving to Google's HCT system with their Material 3 color palette library instead.