-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use CSS gradient rules for transitioning semi-transparent stop-colors #180
Comments
Wouldn't changing that behaviour be a breaking change, though? If it did change, and someone actually wanted that "incorrect" rendering, how would they achieve it? Would adding a new
|
My suggestion was only to apply the CSS pre-multiplied behavior for semi-transparent values in I was not suggesting that the behavior of That said, you're right that this is a |
+1 to Amelia's suggestion. Gradients should interpolate their stop-colors with premultiplied alpha to match CSS. stop-opacity still works separately, so you can get the middle two "bad" results by transitioning stop-color from green to black and stop-opacity from 1 to 0. |
FYI: The screenshot I posted above is how it looks for me in Firefox, Chrome, and Edge on Windows 10. However, CodePen's static screenshot (which I think uses PhantomJS/WebKit) looks different: It seems that the alpha channel is being completely ignored for values set in I'd appreciate someone confirming this result on a recent version of Safari. One more reason we need to clearly define the behavior of semi-transparent colors in |
Safari matches the CodePen static screenshot example. |
Given that we have currently-unspecified behavior, with at least one major non-interoperable implementer, are there any objections to referencing the CSS rules for transitioning colors with alpha when
This achieves my main objective of having the default case consistent between CSS and SVG gradients, while still allowing for flexibility in SVG gradients. |
Note that there was a thread about whether colors should be pre-multiplied. In that thread it is said that Sebastian |
Not at all. Fill-opacity and stroke-opacity should apply as additional effects, masking the stroke or fill, regardless of whether stroke & fill are solid colors, semi-transparent colors, or complex paint (patterns or gradients, which may be partially transparent themselves). If any browser is not multiplying the effect, that's a bug in the browser. But it seems to be well-supported based on my testing. |
Thanks for that link. I didn't realize the CSS rule on pre-multiplied colors was still being debated. Since either effect can be created in SVG using @tabatkins, do you have a final resolution on the matter from the CSS WG? Could you get one? Theoretically, we could link to CSS by reference without locking in the exact details in SVG, but I'd rather not make our spec dependent on something that is still being debated. |
(Incidentally, I think we've finally discovered the case where SVG linear and radial gradients will still be useful even once CSS gradient functions are well supported in SVG fill & stroke. That could be brought up as a benefit on the CSS side, too: if you want more precise, independent control over opacity & color changes, you should in future be able to use an SVG paint server instead of a CSS function.) |
@AmeliaBR Deleted my comment. Must have misremembered. Apologies if it made you do unnecessary research. |
Just remembered the canvas has gradients, too. Again, it would be very nice for both authors and implementers if a simple linear gradient between the same color values creates the same result. Adapting the live demo from MDN to use the lime to transparent gradient results in this demo. All browsers I've tested (Chrome, Edge, Firefox) draw it as a simultaneous color transition to black as well as alpha transition to zero. This is clearly defined in the latest canvas specs at WHATWG:
I'm not sure if this also means no sRGB adjustments? So a canvas gradient should behave the same as an SVG gradient with |
No, the spec is just being a little imprecise; the RGBA tuples for canvas pixels are sRGB, and it's saying that you just linearly interpolate those. |
One way or the other, we should add some rules to the spec, if only to make clear that Safari's "ignore the alpha channel on |
As discussed at the recent telcon, SVG gradients are now defined in the following way:
This means that 'transparent' really means transparent black in SVG. It is equivalent to stop-color='black' and stop-opacity='0'. |
It was obviously not discussed whether to special case Sebastian |
No, it wasn't. Personally I don't see the point. |
I'd like to point out that the SVG 1.1 spec gives the formulation for alpha blending as the premultiplied version. https://www.w3.org/TR/SVG11/masking.html#SimpleAlphaBlending This caused me some considerable confusion about whether the spec requires colors to be specified in premultiplied format or not. |
CSS gradients have special rules to create more aesthetically pleasing results when transitioning to transparent colors. Specifically, user agents are required to transition the pre-multiplied colors, after scaling the color intensity by the alpha value. This gives the intuitive result when transitioning from a color to
transparent
(which is equivalent to transparent black): the color fades to transparent without visually darkening.To create a similar result in SVG, you need to explicitly repeat the
stop-color
value, while changing thestop-opacity
value. This makes sense if you are settingstop-color
andstop-opacity
independently; why would you explicitly transitionstop-color
to black unless that was the effect you wanted?However, when using semi-transparent color values or the
transparent
keyword within thestop-color
property, I would expect to then get the same results as a CSS gradient with the same colors. That is not currently specified anyware and doesn't seem to be how any browser currently implements it.Demo of the various options as a CodePen; Screenshot:
All transition from opaque lime to fully transparent; in all but the first SVG gradient, the final stop is transparent black. The CSS gradient scales the intensity of the color by the alpha value before transitioning, so you don't get the fade to gray effect.
The text was updated successfully, but these errors were encountered: