A while back, as I was working on my custom user style for Google Reader, I noticed a peculiar behavior when I tried to apply a CSS gradient to the feed title section, specifically something like “starting from solid white to 20% transparent, to 80% transparent and finally back to a solid shade of blue”. The result was not was I expected: the transition from solid colors to transparent was murky, mixed with grey. I started experimenting with different combinations of colors and gradients and in different browsers. Finally I discovered that there is a difference in the way browsers interpret ‘transparent’ in gradients: Chrome and Firefox actually treat transparent as ‘black transparent’, causing gradients to add dark shades where none should appear according to the CSS code; Opera on the other hand makes a smooth transition from the starting solid color to transparency (Internet Explorer doesn’t support gradients at all in the stable channel yet).
During this troubleshooting I built a small example on jsFiddle to illustrate the difference: on a red background two boxes filled with vertical gradients: on the left a solid gradient going from white to red and then back to white; on the right white – transparent – white. In my opinion the rendering should be identical, as the right gradient should simply reveal the red background underneath. Instead, Chrome and Firefox add grey strips to the transition from solid to transparent, as you can see in the screenshots and if you visit the test fiddle in those browsers. You get similar results with both the transparent keyword and the
RGBA() function with alpha set to zero or some small value.
- Resulting rendering in Chrome (identical with Firefox)
- Opera rendering – what I actually expected
Of course, the CSS3 specification for linear gradients is still in draft, the browser support is still experimental (i.e. with browser-specific prefixes) so there are bound to be rendering differences. Going through specs, I noticed an example closely resembling mine, as well as an explanation for the strange results you get in Chrome and Firefox (it seems to me that Opera has implemented the specs correctly in this case):
The following example illustrates the difference between a gradient transitioning in pre-multiplied sRGBA and one transitioning (incorrectly) in non-premultiplied. In both of these example, the gradient is drawn over a white background. Both gradients could be written with the following value:
linear-gradient(90deg, red, transparent, blue)
In premultiplied space, transitions to or from "transparent" always look nice:
On the other hand, if a gradient were to incorrectly transition in non-premultiplied space, the colors near "transparent" would noticeably darken to a grayish color, because "transparent" is actually a shorthand for ‘
rgba(0,0,0,0)’, or transparent black.
Which ties again into the debate over Opera starting to support some –webkit-prefixes: even if Opera’s rendering engine picks up the –webkit property, the designer should still test the result in Opera, because it could well be not what he expected (although in this particular case it actually looks better than what you would get in WebKit). The end user should get a better experience anyway, closer to the original design, instead of the fallback for older browsers.
There are other quirks in the linear gradients spec; you can read some very interesting examples in this article.