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

Warning This article was written over six months ago, and may contain outdated information.

Update: I wrote this arti­cle in 2009. In ear­ly 2011 WebKit decid­ed to change their syn­tax to match that used in Fire­fox (and the W3C spec­i­fi­ca­tion). The syn­tax con­tained in these arti­cles will be main­tained for rea­sons of back­wards-com­pat­i­bil­i­ty, but you should use the new syn­tax for the future. I’ve writ­ten a post about the new radi­al gra­di­ent syn­tax.

In the first part of this post I gave a pot­ted his­to­ry of the dif­fer­ing syn­tax­es, and pro­vid­ed an overview of how that affect­ed lin­ear gra­di­ents. In this sec­ond part I’m going to look at radi­al gradients.

Here the syn­tax­es diverge slight­ly more, with WebKit requir­ing more val­ues than Mozil­la; while that adds some flex­i­bil­i­ty, it also increas­es the complexity.

I’ll be using the same page of exam­ples, which you’ll need to view in Safari / Chrome (or oth­er WebKit deriv­a­tive) or Fire­fox 3.6 (beta 3+):

CSS Gra­di­ents com­par­i­son: Mozil­la & WebKit

Radial gradients

As with lin­ear gra­di­ents, the key dif­fer­en­ti­a­tion between the Mozil­la syn­tax and the WebKit syn­tax is that the lat­ter requires a start and end point, where­as the for­mer is con­strained by the bound­ing box.

You can see in this first exam­ple (Radi­al 1) that the Mozil­la syn­tax is much short­er when mak­ing a sim­ple two-colour radi­al gradient:

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

In Mozil­la’s case I set only start and end color-stops; for WebKit I must spec­i­fy a posi­tion (50% 50%) and radius (0 — I’ll explain that lat­er) for the start point, and a posi­tion (50% 50%) and radius (70.5) for the end point, as well as the color-stops.

As far as I can see the radius val­ue has to be a val­ue in pix­els, so in order for the end radius to be the diag­o­nal of the square (where Mozil­la defaults to) you need to use the cal­cu­la­tion (side)(sqrt(2)) — or, do what I did and use this online cal­cu­la­tor.

In the next exam­ple (Radi­al 2) I’ve off­set the cen­ter of the gra­di­ent and set it to end at the fur­thest edge of the con­tain­ing 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 cen­ter off­set but con­strained the radius to the dis­tance of the near­est wall (Radi­al 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, Mozil­la takes a series of con­stants using nat­ur­al lan­guage — farthest-side, closest-side, contain, etc — to set the lim­its of the gra­di­ent, where WebKit accepts only pix­el val­ues. The advan­tage to the for­mer approach is that the syn­tax is sim­pler and no cal­cu­la­tions are required; the dis­ad­van­tage is that if you want to cre­ate a radi­al gra­di­ent that is small­er than the lim­its of the con­tain­ing box, you have to com­bine it with the background-size property.

Next (Radi­al 4) I’ve set the cen­ter of the gra­di­ent to the top-right cor­ner, using three colours equal­ly dis­trib­uted; here’s where you can start to see the WebKit syn­tax start to become real­ly 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 spec­i­fy start and end points (with radii), and also spec­i­fy the stop posi­tion of the mid­dle colour. Both out­comes are the same, but the Mozil­la syn­tax is sig­nif­i­cant­ly easier.

One aspect of WebKit’s syn­tax which allows for more flex­i­bil­i­ty in a gra­di­ent is the start point and end point; by pro­vid­ing two sep­a­rate val­ues you can set the start gra­di­ent at a dif­fer­ent point to the end gra­di­ent, as well as pro­vid­ing dif­fer­ent radius val­ues, allow­ing for effects that Mozil­la can’t eas­i­ly repli­cate (Radi­al 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 ren­dered here (Mozil­la on the left, WebKit on the right):

Comparison of CSS gradients

Achiev­ing the same effect is only pos­si­ble in Mozil­la by using mul­ti­ple val­ues on the background-image prop­er­ty, along with background-size (Update: This isn’t nec­es­sary; see Tab Atkins Jr’s com­ment, below).

Conclusions

While the (orig­i­nal) WebKit syn­tax does allow for a few effects that the sim­pler Mozil­la imple­men­ta­tion can’t eas­i­ly copy, I think these are real­ly edge cas­es and the sim­plic­i­ty of the new­er syn­tax is more than ample com­pen­sa­tion. It seems the CSS WG agree, which is why the sim­ple syn­tax is to become an offi­cial pro­pos­al; I hope the WebKit team accept the pro­pos­al and imple­ment it soon.

It was sug­gest­ed that I also com­pare these with Inter­net Explor­er’s Gra­di­ent fil­ter, but that’s a brows­er-spe­cif­ic imple­men­ta­tion that has no chance of becom­ing a stan­dard, so I did­n’t feel it was suit­able for this arti­cle; per­haps in a future extension.

Update: Just after I fin­ished this arti­cle, Mozil­la Hacks pub­lished an in-depth look at the new syn­tax.

17 comments on
“CSS gradient syntax: comparison of Mozilla and WebKit (Part 2)”

  1. You don’t need to use back­ground-size to get a gra­di­ent of a dif­fer­ent size in the cur­rent syn­tax. Just set your col­or-stops appro­pri­ate­ly, espe­cial­ly the last one. If your last col­or stop is at 50%, then the gra­di­ent will be half the size of normal.

    And yeah, I sort of like the skew effect you can get with the orig­i­nal Webkit syn­tax, but it turns out to com­pli­cate the syn­tax too much. I val­ued the abil­i­ty to do gra­di­ents that depend­ed on the box size more than I val­ued the abil­i­ty to do a skew like that. The orig­i­nal drafts of the syn­tax did have that abil­i­ty, it just grad­u­al­ly dropped out as we hacked on it in the mail­ing list.

  2. Thanks for cor­rect­ing me, Tab; I’ve updat­ed the post to reflect your feed­back. Good work on sim­pli­fy­ing the syn­tax, by the way.

  3. Social com­ments and ana­lyt­ics for this post…

    This post was men­tioned on Twit­ter by angelus12: RT @stopsatgreen CSS gra­di­ent syn­tax: com­par­i­son of Mozil­la and WebKit (Part 2) | Bro­ken Links http://bit.ly/5jHxQt

  4. Hi Peter,

    Unre­lat­ed to the arti­cles (which were very well explained by the way), but when I first tried access­ing your site in Webkit night­ly on a Mac, it crashed my brows­er after warn­ing me about down­load­ing Grablau Sans. Each time I tried to restart the brows­er it would crash again after try­ing to load the page. So I switched to Safari and got the same problem.

  5. Hel­lo Peter, 

    Well done on these two arti­cles. Now time to have fun with it.

  6. @ John — Thanks for let­ting me know. I can’t repli­cate the prob­lem myself, and oth­er Safari users are vis­it­ing the site with no prob­lems. What ver­sion are you using? I’ll try to repli­cate the prob­lem myself.

    @ Jason — Thanks very much. Let me know if you cook up any cool stuff.

  7. Tab,

    Please explain how the Webkit syn­tax does not have “the abil­i­ty to do gra­di­ents that depend­ed on the box size.” It cer­tain seems to have that abil­i­ty to me.

  8. Tab, I see now, sor­ry. In Part 1 it is made clear all the cool dif­fer­ent box-mod­el-aware siz­ing options in the new syn­tax. Very cool.

  9. @John Faulds: After inves­ti­gat­ing this fur­ther, seems like Safari does­n’t like the font-weight prop­er­ty inside @font-face; I need to inves­ti­gate this a lit­tle more.

  10. […] CSS gra­di­ent syn­tax: com­par­i­son of Mozil­la and WebKit (Part 2) […]

  11. […] There are two great arti­cles on this top­ic, delver deep­er into the syn­tax dif­fer­ences: CSS gra­di­ent syn­tax: com­par­i­son of Mozil­la and WebKit and CSS gra­di­ent syn­tax: com­par­i­son of Mozil­la and WebKit (Part 2). […]

  12. Hey these two parts are awesome.
    I real­ly like it and read it more than 5 times to get every­thing in my head.
    I total­ly agree with you con­clu­sion, but there is one prob­lem I can´t solve at the moment.
    You said, with a lit­tle help of TAB that fire­fox is able to show the right result with anoth­er gradient.
    But i am unable to put 2 gra­di­ents in the back­ground-image property.
    How would it look like!

    Thx!

  13. Hi, thanks for your kind com­ments. You can use mul­ti­ple back­ground images in Fire­fox 3.6; you just need to use com­ma-sep­a­rat­ed val­ues for the property:

    background-image: gradient, gradient;

    Just make sure your copy of Fire­fox is updat­ed to 3.6.

  14. While I cer­tain­ly­think that Mozil­las approach is eas­i­er, there’s one thing that Webkit can do but I havn’t seen or fig­ured out to do in Fire­Fox, and that’s “com­pound” gra­di­ents. Can I have mul­ti­ple gra­di­ents lay­ered upon each oth­er, like the WebKit exam­ple imaged here (the top top): http://i2.sitepoint.com/g/nl/tt/cssgradients.jpg

    In WebKit this is done this way (where three gra­di­ents are lay­ered on top of each other):
    back­ground: ‑webkit-gradient(properties 1), ‑webkit-gradient(properties 2), ‑webkit-gradient(properties 3);

    Is there a way to do this in Firefox?

    Henrik Wannheden [May 25th, 2010, 23:30]

  15. You can cer­tain­ly do that in Mozil­la browsers:

    background: { -moz-radial-gradient(20% 50%,circle,white,black 95%,transparent), -moz-radial-gradient(50% 20%,circle,black,white 95%,transparent), -moz-radial-gradient(10% 10%,circle,white,black 95%,transparent); }

    The trick, as you can see, is to remem­ber to set the last colour of each gra­di­ent to ‘trans­par­ent’; if you don’t, the last set colour will fill the rest of the box and oth­er gra­di­ents will be hidden.

  16. […] (ref­er­ence: http://www.broken-links.com) […]

  17. This is one object where the W3C team has nev­er real­ly addressed the issue of gra­di­ent col­ors. It would be great if they would devel­op a stan­dard as it would remove a ‘lot’ of graph­ic work, improve page load times and be more in line with the HTML5-CSS3 stan­dards. Guess we’ll have to wait. :(