Re: [csswg-drafts] [css-color-5] How should negative percentages behave in color-mix()? (#6047)

> If not, what's our question?

There's a few questions:

1. Does your suggested syntax and argument treatment give people results they would expect and be able to predict?

2. If yes, since cross-fade() is doing per-pixel pre-multiplied sRGB color mixing, why shouldn't we apply the same behavior to cross-fade()?

And I think the answer to (1) is *no* once one gets past simple, low-value examples.

For example, under your proposal, `color-mix(rgb, rgb(0 0 100), rgb(100 0 0) -90%)`, the resulting color (after clamping) is `rgb(0 0 190)`.  By subtracting a lot of red, we didn't adjust the hue at all (it stayed exactly on 240deg), but made the blue *much brighter*.

I think an obvious way to try and avoid that brightening effect would be to instead write something like ``color-mix(rgb, rgb(0 0 100) 100%, rgb(100 0 0) -90%)` - this avoids the blue's unstated % getting resolved to 190% to balance things out. But this makes things even worse - now the %s sum to 10%, so you have to rescale, ending up with 1000% and -900%, which post-clamping gives you `rgb(0 0 255)` as a result, the maximum-vividness blue.

Nothing about these situations is *undefined*, it just doesn't give *intuitive* results. (Tho the treatment of `color-mix(rgb, rgb(0 0 100) 90%, rgb(100 0 0) -90%)` *is* undefined, and `color-mix(rgb, rgb(0 0 100) 40%, rgb(100 0 0) -90%)` is defined but *weird* since the rescaling factor is negative.)

If we *didn't* rescale, the operations would at least make a little more sense. `color-mix(rgb, rgb(0 0 100) 100%, rgb(100 0 0) -90%)` would yield `rgb(0 0 100)`, because its red is already non-existent so you can't remove more of it. We'd need to special-case negative values to ignore them when filling in missing %s, so `color-mix(rgb, rgb(0 0 100), rgb(100 0 0) -90%)` is the same. It would also mean that `color-mix(rgb, rgb(0 0 100) 100%, rgb(100 0 0) 100%)` gives a dark purple `rgb(100 0 100)` while `color-mix(rgb, rgb(0 0 100) 10%, rgb(100 0 0) 10%)` gives a *super* dark purple `rgb(10 0 10)`; these are understandable, but still different from what cross-fade() does in similar situations.

> you're just looking at the red coordinate and ignoring the others.

I'm mixing in the RGB space, so I think it's reasonable to assume that the results should be predictable from the RGB data. ^_^  Even if I was thinking in terms of hue, I'd definitely expect removing 20% of a pretty vivid red to make the hue budge by more than 3deg; that's a barely-detectable shift.

-- 
GitHub Notification of comment by tabatkins
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/6047#issuecomment-796355452 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 11 March 2021 01:32:37 UTC