Open Bug 1847421 Opened 11 months ago Updated 2 months ago

(OK)LCH implementation is not according to spec

Categories

(Core :: CSS Parsing and Computation, defect, P2)

Firefox 115
defect

Tracking

()

ASSIGNED

People

(Reporter: bugzilla, Assigned: tlouw)

References

(Depends on 1 open bug)

Details

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/115.0

Steps to reproduce:

  1. Visit https://vasilis.nl/dingen/bugs/oklch.html in a chromium (or webkit) browser
  2. See that the <div>s are not black or white
  3. Conclude that the (ok)lch implementation is not according to spec

Actual results:

The divs are not black nor white.

Expected results:

According to the spec oklch(1 0.4 240) should be white, and oklch(0 0.4 240) should be black:

"If the lightness of an Oklch color is 0% or 0, or 100% or 1.0, the hue component is powerless and the chroma is 0."

https://drafts.csswg.org/css-color-4/#specifying-oklab-oklch

This bug is the reason for not passing several WPT under css/css-color:

https://wpt.fyi/results/css/css-color/lch-009.html?label=master&label=experimental&aligned
https://wpt.fyi/results/css/css-color/lch-l-over-100-1.html?label=experimental&label=master&aligned
https://wpt.fyi/results/css/css-color/oklch-009.html?label=experimental&label=master&aligned
https://wpt.fyi/results/css/css-color/oklch-010.html?label=experimental&label=master&aligned

The same bug is implemented in Webkit and Chromium. I filed bugs there as well.

https://bugs.webkit.org/show_bug.cgi?id=255939
https://bugs.chromium.org/p/chromium/issues/detail?id=1440069

Blocks: css-color-4
Component: Untriaged → CSS Parsing and Computation
Product: Firefox → Core

This looks like a gamut mapping issue which we don't support at the moment. See Bug 1847503.

Assignee: nobody → tlouw
Flags: needinfo?(tlouw)
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true

(In reply to Tiaan Louw from comment #2)

This looks like a gamut mapping issue which we don't support at the moment. See Bug 1847503.

I don’t see how this is a gamut mapping issue. A lightness of 0 doesn’t need to get mapped, it’s always black, and a lightness of 1 is always white. It means that the current calculations are doing something else than what they should be doing.

I’m not sure how the prioritization of bugs works exactly, but I think this should have a higher priority: once this bug is fixed, websites that use (ok)lch will look different, in some cases even completely different. They may turn unusable depending on the use.
Bright colors may turn white, and subtle dark colors may turn completely black. All colors will probably change. Some a bit, others dramatically. The more websites use this color function the bigger the problem will be.

It should be fixed.

I will move this to S2 due to potential user impact. Can't give a timeline, but it will be addressed sooner than later.

For the (ok)lab, (ok)lch colors to be displayed, they are converted to sRGB color space for rendering. This might produce colors that are outside of the sRGB gamut limits, in which case they should be mapped to within limits. Skipping the details, but during this process the lightness of the color is checked to be 0 or 100 and then results in black and white respectively.

Some mention here: https://drafts.csswg.org/css-color-4/#specifying-lab-lch

If the lightness of a Lab color (after clamping) is 0%, or 100% the color will be displayed as black, or white, respectively due to gamut mapping to the display.

And you can also have a look at the pseudocode for mapping here: https://drafts.csswg.org/css-color-4/#binsearch

3. if the Lightness of origin_Oklch is greater than or equal to 100%, return { 1 1 1 origin.alpha } in destination
4. if the Lightness of origin_Oklch is less than than or equal to 0%, return { 0 0 0 origin.alpha } in destination
Severity: S3 → S2
Depends on: 1847503

There’s a javascript implementation of LCH that seems to be accurate. I’m not sure if it’s 100% accurate, but looking at the authors it could very well be. Maybe that helps?

https://css.land/lch/

Authors have been very excited about this feature, as a way to achieve more perceptually-uniform lightness. That was sold to us as the entire reason for this color format in the first place. It seems pretty shocking that all browsers shipped the format in a way that is not even close to perceptually uniform. This is not a small bug - it fundamentally breaks the entire purpose of the color format.

Severity: S2 → S3
Priority: P3 → P2
You need to log in before you can comment on or make changes to this bug.