Open Bug 1886570 Opened 1 month ago Updated 8 days ago

CSS colors: "none" keyword not working correctly

Categories

(Core :: CSS Parsing and Computation, defect)

Firefox 123
x86_64
Windows 10
defect

Tracking

()

People

(Reporter: jbstrater, Unassigned)

References

()

Details

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0

Steps to reproduce:

Open this codepen: https://codepen.io/sidewayss/pen/NWmpjyz

Actual results:

Note that the top row of div elements is gray and black, while the bottom row has vivid color. The only difference between the two rows is "none" versus 0 as the third argument to each color function. These two colors were taken from the "Interpolating colors from different spaces: analogous components" section of the MDN docs page for the CSS <color> data type here: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value.

Expected results:

Open the same codepen in Chrome and both rows of divs look identical, as they should.

Oddly enough, color(display-p3 0.7 0.5 none) displays correctly in this thumbnail-like display of the codepen:

https://codepen.io/collection/RzdyWe

but lch(80% 30 none) still displays as gray.

As I dig further into browser color interpolation, it occurs to me that Chrome might the erroneous one here. I realize that I do not have a full enough understanding of this subject to know which browser is doing it wrong. But I gotta start somewhere, and Firefox is my default browser.

Now open this codepen in Firefox vs Chrome: https://codepen.io/sidewayss/pen/GRLWMmm

It's the opposite! The left and right sides (none vs zero) are flipped between the two browsers.

I was able to reproduce the issue using codepen from comment#3 on Win10x64 using FF build 123.0.
Marking issue as New. If component is not correct please update. Thank you.

Status: UNCONFIRMED → NEW
Component: Untriaged → General
Ever confirmed: true
OS: Unspecified → Windows 10
Hardware: Unspecified → x86_64

In case you care about what's going on in Chrome: the codepen in comment#3 illustrates this bug in Chrome which is now fixed and slated for release in v125: https://issues.chromium.org/issues/331383943

I was viewing this example and again I noticed that browsers are still getting none wrong in general https://codepen.io/sidewayss/pen/NWmpjyz


I've added a manual correction and a reference example with color-mix() in this fork :

https://codepen.io/romainmenke/pen/xxejLQB?editors=1100

none != zero and we must be very careful not to confuse these two concepts.
none behaves as if it were zero in select cases but they are not equal.

Thanks for the fork. As mentioned my previous comment, Chrome has a fix in the pipeline for a May release. AFAIK Safari gets this right. What other browsers do you mean to include in "in general"?

Also note that Chrome and Safari use clipping aka clamping, not gamut mapping, which is what I believe Firefox uses. That produces different (opposite), but correct results for the codepen in comment#3 across these two different methods, so Firefox won't match Chrome and Safari.

Chrome does not have a fix for none in the pipeline.
I don't know what they are doing but I can assure you they are mostly regressing further at this time :(

Safari also didn't get this right otherwise the first row would match the 3rd row in my fork.

Gamut mapping and clipping is only related in so far that Chrome applied heuristics to map 0/100 values to black/white.

See for example : https://codepen.io/romainmenke/pen/NWEaKpL
Firefox actually does the correct thing here. (but it seems it fails in other area's, like your examples)
Safari gives both pink and blue results.
Chrome Canary just regressed and is showing hue rotations again.

I only meant to communicate that Chrome is not showing the expected behavior.
If it is unclear what the expected outcome is then implementers should reach out to the spec editors.

If you have issues with Chrome or Safari I suggest you file bug reports there. If you don't think the fix that Chrome is advancing actually works, then please comment on the bug I filed: https://issues.chromium.org/issues/331383943

I have filed bugs with other browsers, I've been adding WPT tests for all things color the past few years, I've been working with the spec editors to make sure it is as simple and straightforward to get this right :)

Trying to deduce the correct behavior for none based on single colors (not interpolation) as observed in any browser is tricky because they all have various bugs.

Chrome is not fixing none, they are undoing how they handled lightness of 0/100.
They know this.

I only meant to say that if anything is unclear, please do not use other implementations as a reference.
Do reach out to the specification editors, to have better test coverage on WPT.

Thanks for the information. I have reached out to the crew at Color.js and gotten some information there. This was originally a stackoverflow question, that morphed into a discussion on githhub/color.js, that became this bug and the Chrome bug. How do I reach out to the spec editors?

Sorry, I didn't mean that you should reach out to the spec editors :)

Only that if anything is unclear for the engineers that will eventually fix this, then they must not look at the other implementations as a reference.
No vendor has a fully correct implementation for none. So any comparison can lead to false assumptions and even more bugs.

If anything is unclear for the engineers then they should reach out to the spec editors.
They know how and were ;)

The specification discussions happen here : https://github.com/w3c/csswg-drafts
WPT tests are here : https://github.com/web-platform-tests/wpt

Component: General → CSS Parsing and Computation
Product: Firefox → Core

Tiaan, looks like there's some uncertainty as to the correct behavior - maybe you could take a look here and see what (if anything) needs fixing, when you have cycles?

Blocks: css-color-4
Severity: -- → S3
Depends on: 1128204
Flags: needinfo?(tlouw)

Currently Gecko deals with the none hue value as it being missing or powerless. That would generate a grayish color. In contrast, a hue of 0 is red and would turn out pinkish as seen in codepen.

During interpolation if a hue is none, it is essentially ignored and the hue from the other side is used (if not also none).

That being said, I will follow up on the links and discussions mentioned here and ensure we're doing the right thing.

Flags: needinfo?(tlouw)
You need to log in before you can comment on or make changes to this bug.