Closed Bug 1836557 Opened 1 year ago Closed 7 months ago

WPT css-color/parsing/color-computed-color-mix-function.html fails in Firefox

Categories

(Core :: CSS Parsing and Computation, defect)

defect

Tracking

()

RESOLVED FIXED
117 Branch
Tracking Status
firefox117 --- affected

People

(Reporter: dholbert, Assigned: tlouw)

References

(Blocks 1 open bug)

Details

Attachments

(1 file, 1 obsolete file)

Firefox fails this WPT test:
https://wpt.fyi/results/css/css-color/parsing/color-computed-color-mix-function.html?label=master&label=experimental&product=chrome&product=firefox&aligned

It looks like the failing portions there were recently added, for two separate additions to the test:
(1) This github pull request, regarding color-mix and transparent:
https://github.com/web-platform-tests/wpt/pull/39139
...which resulted in these annotated failures:
https://hg.mozilla.org/mozilla-central/rev/3b58a7a217023a04f6064b76c9bfb99fbf67e6bb

Here's a reduced testcase for one of those:
data:text/html,<div id="test" style="background: color-mix(in lch, transparent, lch(0.3 0.4 30deg))">hi<script>alert(getComputedStyle(test).backgroundColor)</script>
In Firefox, that alerts lch(0.3 0.4 15 / 0.5).
In Chrome, that alerts lch(0.3 0.4 30 / 0.5)

(15 vs. 30)

(2) This github pull request, regarding serialization with the "srgb" keyword:
https://github.com/web-platform-tests/wpt/pull/40001
...which resulted in these annotated failures (the rest of our failures in this test):
https://hg.mozilla.org/mozilla-central/rev/2e07c2d9f8628e6615f7333161a2a119dd2f67e9
For these ones, we're off by an order of magnitude or so, in some component. (The test failures are like expected 0.33 but got 84)

Flags: needinfo?(tlouw)

(In reply to Daniel Holbert [:dholbert] from comment #0)

It looks like the failing portions there were recently added, for two separate additions to the test:
(2) This github pull request, regarding serialization with the "srgb" keyword (though I don't see srgb in the
https://github.com/web-platform-tests/wpt/pull/40001

BTW, the associated chrome bugs with this^ test change (which might lend some insight into the failures & code-changes that we might need) was:
https://bugs.chromium.org/p/chromium/issues/detail?id=1427304

Summary: WPT ss/css-color/parsing/color-computed-color-mix-function.html fails in Firefox → WPT css-color/parsing/color-computed-color-mix-function.html fails in Firefox

The failure happens because we are serializing the result in the legacy color format and not in the modern one, so color(srgb 1 1 1 / 1) vs rgba(255, 255, 255, 1).

Taking a look at this.

Flags: needinfo?(tlouw)
Assignee: nobody → tlouw

We change around the way new colors are constructed, because color-mix()
now favors modern syntax even if colors were specified in legacy syntax.

For compatibility, we create default colors in legacy format.

Color interpolation for animation, transitions, etc. still favor the
legacy color syntax for results and that might just be an old way of
doing it and probably should follow the color-mix rules. But that is
not addressed in this patch.

The failing tests with transparent were added because of a very visible lack of interoperability with color-mix() in polar spaces (especially in Oklch and LCH, which often use a different code path to mixing in HSL or HWB). This was raised as an issue on CSS Color 4, which after a fair bit of discussion and some spec improvements was closed out because the spec was now correct and WPT matched the spec; the ramaining failures are browser bugs.
https://wpt.fyi/results/css/css-color/parsing/color-computed-color-mix-function.html?label=master&label=experimental&aligned

WPT results (Chrome passes 100%, Safari and Firefox both have the same bugs with transparent and with mixing in hsl or hwb)
https://wpt.fyi/results/css/css-color/parsing/color-computed-color-mix-function.html?label=master&label=experimental&aligned

color-mix() now favors modern syntax even if colors were specified in legacy syntax.

Right, because mixing in hsl or hwb used to require gamut mapping to bring the colors to be mixed inside the sRGB gamut. We now allow out of gamut colors, consistent with the other color spaces, but that means that rgba() can't be used to serialize the result because of the clamping to [0,255]. Instead we use color(srgb ...) which can represent out of gamut colors (and also has better resolution than 8 bits per component).

For these ones, we're off by an order of magnitude or so, in some component. (The test failures are like expected 0.33 but got 84)

No no this is because of the change of format. 0.33 * 255 = 84.15 which rounds to 84. So the computations are correct it is just down to color() using a [0,1.0] range not [0,255].

(15 vs. 30)

The bug is in step 8 (rectangular to polar conversion) of Converting Colors
https://drafts.csswg.org/css-color-4/#color-conversion

If dest-rect is not the same as dest, in other words dest is a cylindrical polar color representation, convert from dest-rect to dest, and let this be col2. This may produce missing components.

and 4.4. “Missing” Color Components and the none Keyword
https://drafts.csswg.org/css-color-4/#missing-color-component

and in particular 9.5. Converting Lab or Oklab colors to LCH or Oklch colors
https://drafts.csswg.org/css-color-4/#lab-to-lch

For extremely small values of a and b (near-zero Chroma), although the visual color does not change from being on the neutral axis, small changes to the values can result in the reported hue angle swinging about wildly and being essentially random. In CSS, this means the hue is powerless, and treated as missing when converted into LCH or Oklch; in non-CSS contexts this might be reflected as a missing value, such as NaN.

When converting colors ready for interpolation, Firefox is currently not doing that step for HSL, HWB, Oklch and LCH which means that black (including transparent), white, and all grays end up with a hue angle of 0 instead of none. Which is red in HSL and a reddish-pink in OkLCH. This has a very visible effect on color-mix() and on gradients. For example, a gradient from white to blue in any polar colorspace starts off with a red hue at the white end, giving unexpected purples and reds.

Duplicate of this bug: 1840717
Attachment #9344042 - Attachment description: WIP: Bug 1836557 - The result of a color-mix() is always in the modern color syntax r=emilio,#layout-reviewers → Bug 1836557 - The result of a color-mix() is always in the modern color syntax r=emilio,#layout-reviewers
Attachment #9338864 - Attachment is obsolete: true
Attachment #9344042 - Attachment description: Bug 1836557 - The result of a color-mix() is always in the modern color syntax r=emilio,#layout-reviewers → WIP: Bug 1836557 - The result of a color-mix() is always in the modern color syntax r=emilio,#layout-reviewers
Attachment #9344042 - Attachment description: WIP: Bug 1836557 - The result of a color-mix() is always in the modern color syntax r=emilio,#layout-reviewers → Bug 1836557 - The result of a color-mix() is always in the modern color syntax r=emilio,#layout-reviewers
Depends on: 1844333
Depends on: 1844332
Pushed by tlouw@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/748ea6c2376b
The result of a color-mix() is always in the modern color syntax r=emilio
Status: NEW → RESOLVED
Closed: 11 months ago
Resolution: --- → FIXED
Target Milestone: --- → 117 Branch

Reopening as there are more failures due to other issue. See dependencies.

Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Depends on: 1848138

All the test pass now. Mostly fixed by various smaller fixes related to interpolation.

Status: REOPENED → RESOLVED
Closed: 11 months ago7 months ago
Resolution: --- → FIXED

Curiously, there are two (new?) tests which all browsers are failing:

  • Property color value 'color-mix(in lch, white, blue)'
  • Property color value 'color-mix(in lch, white 10%, blue)'
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: