Cross browser gradients with CSS3 and SVG

February 3, 2011 at 8:19 pm 4 comments

svg-w3c-v.pngSince I’m currently taking a course on SVG (Scalable Vector Graphics) with the W3C I thought of a very simple yet cool application for it: gradients.

Most of you certainly know how to visually enhance your web apps, using proprietary CSS gradient properties in Webkit or Gecko based browsers (like Firefox, Chrome or Safari). But CSS gradients aren’t (yet) available to IE or Opera. From this perspective CSS gradients can only be used for progressive enhancements on a small subset of browsers (at least on the desktop, most mobile browsers are Webkit based) and you must be careful with browsers that won’t display them. However Opera has the best support for SVG and Microsoft is committed to SVG with IE9. So bang! Now SVG can complement CSS3 to widen your audience for cool stuff without the need for graphics or images.

Note that this post won’t go into the details of gradients (I’ll point to various resources at the end of the article) but will simply walk you through cross browser gradients implementation using both CSS3 and SVG. So let’s dot it.

As usual I’ll start with a very simple HTML (5) code snippet:

<!DOCTYPE html>
<html lang="en">
	<meta charset="utf-8">
	<title>Cross browser gradients with CSS3 and SVG</title>
		/* CSS properties should go in there */
	<div>A simple linear gradient</div>

And the accompanying CSS rules:

div {
	width: 50%;
	padding: 1em;
	font-size: 2em;
	font-weight: bold;
	background-color: orange;
	background-image: url(gradient.svg);
	background-image: -moz-linear-gradient(left, blue, yellow 30%, orange 60%, red);
	background-image: -webkit-gradient(linear, left top, right top, from(blue), color-stop(0.3, yellow), color-stop(0.6, orange), to(red));

The first 4 rules in the CSS are just there to set the scene and make the text inside the DIV more visible. Obviously the gradient stuff happens with the background-image properties. Basically we’ve defined an horizontal linear gradient that goes from blue to red with intermediate shades of yellow and orange. You can see the result with the image below:


Now the order in which we’ve defined these rules is important. In CSS the last valid rule has precedence in case of a conflict (which is the case here since we’ve set 3 distinct background-image rules). Chrome for instance understands the 1st and 3rd background-image rules, but will only apply the last one (i.e. the 3rd one, the proprietary -webkit-gradient). Since the -moz-linear-gradient property is proprietary to Mozilla browsers (Gecko based) it’s not supported by Webkit and thus isn’t an issue here. Similarly Firefox will apply the last valid rule it understands i.e. the -moz-linear-gradient one.

In any case Webkit and Gecko browsers won’t care about the 1st rule which is both great and important. Why? Because the 1st rule implies an HTTP GET request to retrieve the gradient.svg file from a web server. Since Webkit and Gecko both have the ability to display gradients using CSS3, downloading an additional useless file wouldn’t be at all effective. Hence the need to put the background-image: url(gradient.svg) rule first because it’s then ignored by Webkit and Gecko engines when trying to resolve which rule is supposed to apply.

Now what about IE9 and Opera?

As you can imagine they can’t understand the proprietary 2nd and 3rd background-image rules and thus fall back to the 1st one. Again the great thing here is that the gradient.svg file is only downloaded by browsers which don’t support the proprietary CSS gradient syntaxes.

But what does this gradient.svg file looks like? Here it is:

<svg xmlns="" width="100%" height="100%">
<linearGradient id="g">
	<stop offset="0" stop-color="blue" />
	<stop offset="0.3" stop-color="yellow" />
	<stop offset="0.6" stop-color="orange" />
	<stop offset="1" stop-color="red" />
<rect x="0" y="0" width="100%" height="100%" fill="url(#g)" />

SVG is based on XML so it’s simply a text file. I’ll assume its content is simple enough to be self understandable. We define a linear gradient with the same colors and color stops than those of the CSS3 gradients. Then we create a rectangle and apply the gradient to it. Remember that the gradient is used as a DIV background and a DIV is a rectangle. SVG allows for much more complex patterns, but this post isn’t about an SVG training. Since we’ve defined the width and height both to 100% it insures the DIV will be fully covered whatever its size (which is an advantage compared to a fixed size gradient image file that may need to be stretched over the surface of the DIV to fill it entirely).

As you can see using an SVG file for gradients is quite straightforward. If you’re used to Webkit and Gecko CSS3 gradient syntaxes you shouldn’t really feel lost. Also just to reassure you SVG supports linear gradients other than horizontal as well as complex cases of radial gradients. Again this post focuses on the usage not on the endless gradient possibilities with both CSS3 and SVG.

One more important thing though. In order to be recognized by the browsers you must make sure that your web server returns the image/svg+xml MIME type for .svg files. You can easily do that with Apache servers for an example, by putting a .htaccess file in the directory holding your .svg files, that contains the following lines:

		AddType image/svg+xml svg
		AddType image/svg+xml svgz

Now coming back to the CSS. As you may have noticed I’ve taken the precaution to define a background-color. This is the ultimate fall back for browsers that don’t understand the proprietary CSS gradient rules and don’t know as well what to do with the SVG file (like IE up to version 8). You should always remember to define a background-color and take some time to check your pages without gradients or images (think about cases where images and javascript are restricted for security reasons) to see what they look like without any visual enhancement.

As usual I’ve prepared some files for you to download so you can make your own tests:

Make sure to download both files and save them in the same directory.

What do you think? Do you use any other recipes (other than gradient images) to achieve similar results? Please share your feedback in the comments after the resources section.



Entry filed under: Web Development. Tags: , , .

Super sleek CSS3 only sliding menu tutorial

4 Comments Add your own

  • 1. Johnie Spiney  |  February 10, 2011 at 2:19 pm

    I simply want to mention I am newbie to blogs and actually savored your blog site. Most likely I’m likely to bookmark your site . You definitely come with good article content. Bless you for sharing with us your web site.

    • 2. p6ril  |  March 1, 2011 at 9:16 am

      Thanks Johnie I appreciate.

  • 3. Micah Cochran  |  March 1, 2011 at 3:54 am

    The current W3C CSS3 proposal has gradients in it.

    • 4. p6ril  |  March 1, 2011 at 9:12 am

      Hi Micah,

      you’re perfectly right. However the W3C CSS3 Image Values and Replaced Content recommendation is still a working draft and the “standard” gradient syntax it describes (which is the one adopted by mozilla by the way) isn’t supported by any browser yet. Hence the need to use proprietary extensions when available for now.

      Then it doesn’t change the fact that IE9 and Opera both don’t support CSS3 gradients at all for the time being. The point of this article is to provide a valid alternative to CSS3 gradients with SVG for these browsers. Provided you’ve installed the Adobe SVG Viewer plugin, SVG gradients would even show in earlier versions of IE.

      Obviously you could also use images, but SVG being text it’s easier to write (and modify), not to mention it compresses well when transmitted over the net (provided your web server compresses content on the fly) so it’s easy on the bandwidth compared to images. Plus it’s been around for quite a long time now and it’s fairly well supported.

      As I see it, it’s a nice way to reach a larger audience with progressive enhancements in your web site while still being compliant with W3C recommendations.

      I just hope your enjoyed the post anyway.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed


February 2011
« Jul    

Most Recent Posts

%d bloggers like this: