CSS gradient syntax: comparison of Mozilla and WebKit (Part 2)

Update: I wrote this article in 2009. In early 2011 WebKit decided to change their syntax to match that used in Firefox (and the W3C specification). The syntax contained in these articles will be maintained for reasons of backwards-compatibility, but you should use the new syntax for the future. I’ve written a post about the new radial gradient syntax.

In the first part of this post I gave a potted history of the differing syntaxes, and provided an overview of how that affected linear gradients. In this second part I’m going to look at radial gradients.

Here the syntaxes diverge slightly more, with WebKit requiring more values than Mozilla; while that adds some flexibility, it also increases the complexity.

I’ll be using the same page of examples, which you’ll need to view in Safari / Chrome (or other WebKit derivative) or Firefox 3.6 (beta 3+):

CSS Gradients comparison: Mozilla & WebKit

Radial gradients

As with linear gradients, the key differentiation between the Mozilla syntax and the WebKit syntax is that the latter requires a start and end point, whereas the former is constrained by the bounding box.

You can see in this first example (Radial 1) that the Mozilla syntax is much shorter when making a simple two-colour radial gradient:

-moz-radial-gradient(green, yellow);
-webkit-gradient(radial, center center, 0, center center, 70.5, from(green), to(yellow));

In Mozilla’s case I set only start and end color-stops; for WebKit I must specify a position (50% 50%) and radius (0 — I’ll explain that later) for the start point, and a position (50% 50%) and radius (70.5) for the end point, as well as the color-stops.

As far as I can see the radius value has to be a value in pixels, so in order for the end radius to be the diagonal of the square (where Mozilla defaults to) you need to use the calculation (side)(sqrt(2)) — or, do what I did and use this online calculator.

In the next example (Radial 2) I’ve offset the center of the gradient and set it to end at the furthest edge of the containing box:

-moz-radial-gradient(40% 40%, farthest-side, green, yellow);
-webkit-gradient(radial, 40% 40%, 0, 40% 40%, 60, from(green), to(yellow));

And then used the same center offset but constrained the radius to the distance of the nearest wall (Radial 3):

-moz-radial-gradient(40% 40%, closest-side, green, yellow);
-webkit-gradient(radial, 40% 40%, 0, 40% 40%, 40, from(green), to(yellow));

As you can see, Mozilla takes a series of constants using natural language — farthest-side, closest-side, contain, etc — to set the limits of the gradient, where WebKit accepts only pixel values. The advantage to the former approach is that the syntax is simpler and no calculations are required; the disadvantage is that if you want to create a radial gradient that is smaller than the limits of the containing box, you have to combine it with the background-size property.

Next (Radial 4) I’ve set the center of the gradient to the top-right corner, using three colours equally distributed; here’s where you can start to see the WebKit syntax start to become really unwieldy:

-moz-radial-gradient(right top, green, yellow, blue);
-webkit-gradient(radial, right top, 0, right top, 141, from(green), color-stop(50%, yellow), to(blue));

With WebKit I again have to specify start and end points (with radii), and also specify the stop position of the middle colour. Both outcomes are the same, but the Mozilla syntax is significantly easier.

One aspect of WebKit’s syntax which allows for more flexibility in a gradient is the start point and end point; by providing two separate values you can set the start gradient at a different point to the end gradient, as well as providing different radius values, allowing for effects that Mozilla can’t easily replicate (Radial 5):

-moz-radial-gradient(60% 60%,circle contain,yellow,green 75%,rgba(255,255,255,0));
-webkit-gradient(radial,45% 45%,5,60% 60%,40,from(yellow),color-stop(75%, green),to(rgba(255,255,255,0)));

You can see how that is rendered here (Mozilla on the left, WebKit on the right):

Comparison of CSS gradients

Achieving the same effect is only possible in Mozilla by using multiple values on the background-image property, along with background-size (Update: This isn’t necessary; see Tab Atkins Jr’s comment, below).

Conclusions

While the (original) WebKit syntax does allow for a few effects that the simpler Mozilla implementation can’t easily copy, I think these are really edge cases and the simplicity of the newer syntax is more than ample compensation. It seems the CSS WG agree, which is why the simple syntax is to become an official proposal; I hope the WebKit team accept the proposal and implement it soon.

It was suggested that I also compare these with Internet Explorer’s Gradient filter, but that’s a browser-specific implementation that has no chance of becoming a standard, so I didn’t feel it was suitable for this article; perhaps in a future extension.

Update: Just after I finished this article, Mozilla Hacks published an in-depth look at the new syntax.