web-platform-tests / web-platform-tests/interop
Gamut mapping
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 524
- Forks
- 35
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 10
Description
Description
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:
#0075ff |
oklch(from #0075ff 97% c h) |
oklch(from #0075ff 97% c h), gamut mapped to P3 |
|
|---|---|---|---|
| Color |
|
|
|
| Color relative to 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.
CSS Color 4 defines three gamut mapping algorithms that browsers can pick from (comparison), but so far only Firefox has shipped an implementation. Soon, it may be too late to fix this due to web compat.
This was previously submitted in 2024 by @romainmenke in #443 and rejected on the basis of lacking testing infrastructure. There are currently more tests than there were back then. Canvas makes it easier to test at least for specific colorSpace values.
In terms of implementations, Firefox has implemented GM behind a flag and Chrome and WebKit are reportedly looking into it.
Specification
https://www.w3.org/TR/css-color-4/#css-gamut-mapping
web-feature
https://github.com/web-platform-dx/web-features/issues/4286
Test Links
https://wpt.fyi/results/css/css-color/lch-009.html
https://wpt.fyi/results/css/css-color/lch-010.html
https://wpt.fyi/results/css/css-color/lch-l-over-100-1.html
https://wpt.fyi/results/css/css-color/lch-l-over-100-2.html
https://wpt.fyi/results/css/css-color/oklch-009.html
https://wpt.fyi/results/css/css-color/oklch-010.html
Additional Signals
At CSS Day, gamut mapping was the top requested feature:
In State of CSS, color pain points revolve around creating color ramps, or how confusing oklch is, both issues that are largely or completely solved by GM (the site is broken right now, so I can't cite specific things, this is from memory).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the CSS Color 4 gamut-mapping specification and the linked WPT cases, including lch-009.html, lch-010.html, lch-l-over-100-1.html, lch-l-over-100-2.html, oklch-009.html, and oklch-010.html. Compare current browser results and existing test coverage, then determine the interoperability work needed. Done means the agreed gamut-mapping behavior is implemented and the relevant tests pass across implementations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css
- Domain
- testing-qa, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100