https://drafts.csswg.org/css-color-4/#interpolation-alpha
https://drafts.csswg.org/css-color-5/#color-mix-with-alpha
This example is 25% semi-opaque red and 75% semi-opaque green. mixed in sRGB. Both the correct (premultiplied) and incorrect (non-premultiplied) workings are shown. color-mix(in srgb, rgb(100% 0% 0% / 0.7) 25%, rgb(0% 100% 0% / 0.2)); The calcuation is as follows:
rgb(100% 0% 0% / 0.7) when premultiplied, is [0.7, 0, 0]
rgb(0% 100% 0% / 0.2) when premultiplied, is [0, 0.2, 0]
the premultiplied, interpolated result is [0.7 * 0.25 + 0 * (1 - 0.25), 0 * 0.25 + 0.2 * (1 - 0.25), 0 * 0.25 + 0 * (1 - 0.25)] which is [0.175, 0.150, 0]
the interpolated alpha is 0.7 * 0.25 + 0.2 * (1 - 0.25) = 0.325
the un-premultiplied result is [0.175 / 0.325, 0.150 / 0.325, 0 / 0.325] which is [0.53846, 0.46154, 0]
so the mixed color is color(srgb 0.53846 0.46154 0 / 0.325)
As best as I can work out this algorithm will always cause any mix with transparent
to be the other color but with a different alpha value.
It should be impossible to get a color change from mixing with transparent
.
Yet in browsers you can get very large hue shifts by mixing with transparent
.
https://codepen.io/romainmenke/pen/zYJLRQJ
If I am reading all relevant bits correctly the steps should be :
Unless transparent
isn't zero in all components in all colorspaces we always interpolate with [0 0 0]
The ratio between the two colors is the inverse of the value used when un premultiplying.
So you always end up with the non transparent
input color.
This might also be the result of implementations not handling powerless/missing components correctly : https://github.com/w3c/csswg-drafts/issues/8609
Questions :
transparent
instead of white
?transparent
always 0
or none
for all components in all color spaces?Have been looking at this a bit more.
As far as I can tell any mix with a color that has 0
alpha
, (including, but not limited to transparent
) will always just be the other color for rectangular orthogonal
color spaces.
For cylindrical polar
color spaces the colors will only interpolate the hue's, all other components will always just come from the other color.
When mixing with transparent
the hue
happens to be a missing/powerless component and hue
isn't premultiplied / unpremultiplied
I think the main issue here is a lack of test coverage in WPT and some implementation bugs.
Missing tests :
color-mix
with transparent
in both rectangular orthogonal
and cylindrical polar
color spacescolor-mix
with several colors with 0
alpha
in both rectangular orthogonal
and cylindrical polar
color spacesThere are a few tests with none
alpha
, but maybe not sufficient.
Agree that these tests would help. I believe at this point the specification is correct (but perhaps more examples would help).