I'm currently on parental leave till September 1st. Until then, I will not be available to read comments, e-mails, tweets and Facebook messages.

If you are interested in my writings, please subscribe to my RSS feed and follow me on Twitter.

CSS gradients for all web browsers, without using images

One thing that is quite nice is that we now have the ability to create gradients in our pages just from CSS code, and without the use of any images.

Syntax options and web browser support

The good news is that there is web browser support for CSS gradients in Firefox, Safari, Google Chrome and Internet Explorer (Opera will most likely add it soon too). The bad news is that, for a couple of reasons, the implementation in each web browser is different from the other. In IE’s case, it’s because it’s based on their ancient approach that stems form IE 5.5. For WebKit-based web browsers (like Safari and Google Chrome), they were the first ones to suggest it, based on the approach for canvas, but this was later changed by the CSS WG, and the new syntax is now the one implemented in Firefox (and I guess this syntax will later make into WebKit-based web browsers as well).

There are two great articles on this topic, delver deeper into the syntax differences: CSS gradient syntax: comparison of Mozilla and WebKit and CSS gradient syntax: comparison of Mozilla and WebKit (Part 2).

So, as of now, we have have CSS gradients support for:

  • Firefox 3.6
  • Safari 4
  • Google Chrome
  • Intenet Explorer 5.5

Examples

Let’s look at some samples code:

Linear gradient, from top

This will show a simple linear gradient, going from top to bottom in a element.

<style>
	#gradient {
		color: #fff;
		height: 100px;
		padding: 10px;
		/* For WebKit (Safari, Google Chrome etc) */
		background: -webkit-gradient(linear, left top, left bottom, from(#00f), to(#fff));
		/* For Mozilla/Gecko (Firefox etc) */
		background: -moz-linear-gradient(top, #00f, #fff);
		/* For Internet Explorer 5.5 - 7 */
		filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FF0000FF, endColorstr=#FFFFFFFF);
		/* For Internet Explorer 8 */
		-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#FF0000FF, endColorstr=#FFFFFFFF)";
	}
</style>

<div id="gradient">
	I haz gradient
</div>

Rendered version

I haz gradient

Linear gradient, from left

This gradient is rendered from left to right, for 70% of the width of the element. The color stop after 70% will not work in Internet Explorer; “interestingly” enough its FinishX and GradientSize properties doesn’t apply to the Gradient filter

<style>
	#gradient-with-stop {
		color: #fff;
		height: 100px;
		padding: 10px;
		/* For WebKit (Safari, Google Chrome etc) */
		background: -webkit-gradient(linear, left top, right top, from(#00f), to(#fff), color-stop(0.7, #fff));
		/* For Mozilla/Gecko (Firefox etc) */
		background: -moz-linear-gradient(left top, #00f, #fff 70%);
		/* For Internet Explorer 5.5 - 7 */
		filter: progid:DXImageTransform.Microsoft.gradient(startColorStr=#FF0000FF, endColorStr=#FFFFFFFF, GradientType=1);
		/* For Internet Explorer 8 */
		-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#FF0000FF, endColorstr=#FFFFFFFF, GradientType=1)";
	}
</style>

<div id="gradient-with-stop">
	I haz gradient
</div>

Rendered version

I haz gradient 2

Radial gradient

Time to get a little bit funky with radial gradients! From what I have seen, there is no support for radial gradients in Internet Explorer.

<style>
	#gradient-radial {
		color: #fff;
		width: 100px;
		height: 100px;
		padding: 10px;
		/* For WebKit (Safari, Google Chrome etc) */
		background: -webkit-gradient(radial, 40% 40%, 0, 40% 40%, 60, from(#ffffa2), to(#00f));
		/* For Mozilla/Gecko (Firefox etc) */
		background: -moz-radial-gradient(40% 40%, farthest-side, #ffffa2, #00f);
		/* For Internet Explorer */
		/* As if... */
	}
</style>

<div id="gradient-radial">
	I haz gradient
</div>

Rendered version

I haz radial gradient

Thoughts

For simple linear gradients, this offers quite a nice and simple way to offer and control it directly through CSS. Unfortunately, lack of support in Internet Explorer doesn’t make it as useful as it could be.

More reading

113 Comments/Reactions

  • #1 Mathias Bynens
    February 15th, 2010 at 12:18

    Nice reference, Robert!

    Like Jonathan Snook said, “nothing says CSS3 like repeating a background declaration 4 frickin’ times.”

  • #2 David
    February 15th, 2010 at 13:15

    Thanks for collecting all the different puzzle pieces for us!

  • #3 Gradienten
    February 15th, 2010 at 14:04

    [...] (Gradienten) mit CSS3. Nette Idee. Einen Erfahrungsbericht dazu gibt's bei Robert Nyman. Ich habe einen Stil (Leder), bei dem sich die Anwendung vermutlich rentieren würde. Muss ich in [...]

  • #4 anthony spano
    February 16th, 2010 at 13:14

    dude, just use background images for gradients – its so much more efficient than writing 6 different statements for each browser.

  • #5 Sam
    February 16th, 2010 at 13:32

    It’s not for ALL web browsers. There is no solution for Opera.

  • #6 Michael
    February 16th, 2010 at 14:13

    My understanding as per http://snook.ca/archives/html_and_css/multiple-bg-css-gradients is that Opera 10.5 (beta on Windows, alpha on other platforms) DOES support CSS gradients. Please confirm.

  • #7 Robert Nyman - author
    February 16th, 2010 at 14:24

    Mathias,

    Thanks! And yes, I agree with Jonathan. :-)

    David,

    You are welcome!

    anthony,

    Images aren’t preferred because of the performance impact with multiple HTTP requests and sheer file size. Also, maintenance-wise, chaining a line of code is a lot easier, faster and cheaper (given software costs for image editing) than having images.

    Sam,

    True, although I believe it is upcoming in Opera.

    Michael,

    I have heard so, but not tested. If you’re on Windows, feel free to download the beta and test (most likely with the Opera prefix -o-).

  • #8 links for 2010-02-16 « burningCat
    February 16th, 2010 at 15:07

    [...] CSS gradients for all web browsers, without using images [...]

  • #9 links for 2010-02-16 | Don't mind Rick
    February 16th, 2010 at 15:07

    [...] CSS gradients for all web browsers, without using images [...]

  • #10 CSS 3 Gradients – Codecandies
    February 16th, 2010 at 15:55

    [...] Einige der neuen CSS3-Funktionalitäten sind ein wenig schwer zu merken, vor allem da man sich hinsichtlich der Syntax bei Webkit und Mozilla noch nicht ganz einige ist. Ein schönes Beispiel sind gradients, für die es sogar noch M$ Filter gibt, den man setzen kann, wenn man das will. Und nur bei linearen Farbverläufen. Einmal zum Mitschreiben. [...]

  • #11 Stefan Manastirliu
    February 16th, 2010 at 15:57

    I can’t see it with Firefox 3.5.7

  • #12 Robert Nyman - author
    February 16th, 2010 at 16:04

    Stefan,

    That is because Firefox 3.6 is the first version to support it, as written in the supported web browsers list.

  • #13 Aaln
    February 16th, 2010 at 20:48

    Hmmm… For some reason, I don’t see the sample effects under Firefox 3.5/Kubuntu Linux.

  • #14 Robert Nyman - author
    February 17th, 2010 at 8:22

    Aaln,

    Right, because as mentioned in the post, support is from Firefox 3.6 and up.

  • #15 Richard
    February 17th, 2010 at 12:54

    It’s a creative solution, but not ideal until a) there is better browser support (admittedly support is reasonable) and b) one solution works across all the browsers.

    In the meantime I don’t think that using background images for gradients is really that big a deal. A quick experiment shows that a one pixel wide, 1100 pixel high gradient comes in at under 1k filesize, and if the number of http requests is an issue then of course gradients can be stored within a CSS sprite.

  • #16 Peter Gasston
    February 17th, 2010 at 17:31

    Thanks for the links to my articles, Robert; this is a very good companion piece.

    FWIW, the WebKit team have raised a couple of issues with the new syntax, so it may change slightly in the near future.

  • #17 Robert Nyman - author
    February 18th, 2010 at 9:47

    Richard,

    In terms of web browser support, being supported in all web browsers but Opera (and on its way there), I think that’s pretty good. Besides, for now, Opera could just get a solid background color as a fallback.

    When it comes to image size, that is overall true, but with things like Serious Memory Leak Issue With 24-Bit PNG Images With Alpha Transparency In Internet Explorer it could become an issue.

    Also, file size is one factor, but I believe HTTP requests and maintainability are important parts too. Sure, CSS sprites is an option too, but can be difficult to create, and very tedious to maintain.

    At the end of the day, though, I think it comes down to what kind of gradient you want and how you will use it. This approach seems like a reasonable option for simple use cases.

    Peter,

    No, thank you for very good articles! And yes, we’ll see there the syntax ends up in the long run.

  • #18 bruce
    February 19th, 2010 at 13:44

    Opera has long supported background gradients, using SVG background-images. The syntax is not too dissimilar from CSS gradients, see http://tutorials.jenkov.com/svg/svg-gradients.html

  • #19 Friday Focus 02/19/10: Fixed | Devlounge
    February 19th, 2010 at 13:59

    [...] CSS – CSS gradients for all web browsers, without using images [...]

  • #20 Robert Nyman - author
    February 19th, 2010 at 17:52

    bruce,

    Thanks for the tip. However, while it’s a valid option, the idea was to offer everything from CSS and not to have separate code branching (and SVG, while interesting, is a completely different story :-) ).

  • #21 dawn
    February 19th, 2010 at 18:12

    It is worth pointing out that Microsoft’s filters don’t perform well (the DX stands for DirectX) if you have more than 1 or 2 on the page (instances, not style declarations) the CPU will ramp up and the page rendering freeze for a few moments while it does its thing.

    If you have 1 or 2 large page backgrounds then you’ll be ok, but say you had a gradient on a number of things, (for example a list of results, promo boxes, etc.) you may find you are better off with images.

  • #22 Robert Nyman - author
    February 19th, 2010 at 18:36

    dawn,

    Absolutely, good point. One need to test in each specific use case, evaluate the results and take it from there.

  • #23 klima servisi
    February 22nd, 2010 at 8:29

    Very usefull. Thank you very much this shared.

  • #24 Robert Nyman - author
    February 23rd, 2010 at 16:11

    klima servisi,

    You’re welcome!

  • #25 Amarnath
    February 23rd, 2010 at 18:00

    The Gradient Style Doesnt apply in The Firefox 3.5.3?

    Any Suggestions are appreciated.

  • #26 Robert Nyman - author
    February 23rd, 2010 at 22:32

    Amarnath,

    As mentioned in the blog post and previous comments, the gradient support in Firefox is from version 3.6 and up.

  • #27 JP
    February 24th, 2010 at 22:30

    A note for IE5.5+ developers: Gradients aren’t applied to just any element!

    The object that the filter is applied to must have layout before the filter effect will display. You can give the object layout by setting the height or width property [or] setting the position property to absolute…

    MSDN Gradient Filter

  • #28 Robert Nyman - author
    February 25th, 2010 at 10:18

    JP.

    Good point. I’m so used to having to trigger hasLayout in IE that I tend to forget about mentioning it.

  • #29 Michael
    March 4th, 2010 at 16:30

    Thanks for this article, helped a lot.

  • #30 Robert Nyman - author
    March 4th, 2010 at 16:34

    Michael,

    You’re welcome!

  • #31 Speed Up with CSS3 Gradients Ajax Help W3C Tag
    March 5th, 2010 at 5:11

    [...] Robert Nyman: CSS gradients for all browsers [...]

  • #32 Speed Up with CSS3 Gradients | pro2go Designs Blog
    March 10th, 2010 at 9:46

    [...] Robert Nyman: CSS gradients for all browsers [...]

  • #33 Rizo
    March 12th, 2010 at 18:31

    works like a charm, cheerios :)

  • #34 Aleko
    March 12th, 2010 at 20:11

    Nice, but IE can only apply the filter on a few elements. I don’t have a comprehensive list, but I found it doesn’t work on THEAD, TR, or TD, for example, although it does work on TABLE.

  • #35 SILT: Canvas/SVG, jQuery, LESS update « Superdrivel
    March 19th, 2010 at 12:26

    [...] One issue I had with LESS recently was getting the mixin syntax working with IE’s filter syntax. The equal signs throw the compiler off. I was doing terrible IE things because I was doing cross-browser pure CSS gradients. [...]

  • #36 Drop shadow with CSS for all web browsers – Robert's talk
    March 25th, 2010 at 23:54

    [...] CSS gradients for all web browsers, without using images [...]

  • #37 Andy
    April 8th, 2010 at 16:31

    Thanks for this good summary of the different implementations.

    Sadly this is again a bad example for having no standards. We are forced to play in different sandpit’s instead of one. Why is it not possible to find a solution, that one implementation works in all browsers. Sure – we would need to bring all companies together. And that this is kind of a real big problem is shown in trying to get the new ECMA Script release.

    Unless we have more standards, we have a lot of errors (JavaScript) or at least smashed designs (CSS).

    On the other hand we all love this stuff for sure and it’s good to see how it works. Again – thanks a lot Robert ;-)

    Cheers

    Andy

  • #38 Remy Sharp
    April 8th, 2010 at 16:32

    Okay, for arguments sake:

    Unfortunately, lack of support in Internet Explorer doesn’t make it as useful as it could be.

    Can you give me once instance where a gradient is useful. It’s a design feature, and not content. It helps with making stuff look actionable, but then decent design would probably not rely entirely on gradients.
    I’d encourage web developers and designers to steer away from IE filters, if only for the performance issues related to the rendering. Poor IE6 has trouble enough just drawing the page and dealing with our JavaScript, let alone gradient rendering (that said – anyone wants to prove me wrong there, I’d love to see some performance stats on filters vs. native CSS).
    Just my argumentative 2 cents worth ;-)

  • #39 Robert Nyman - author
    April 8th, 2010 at 16:40

    Andy,

    Well, it is going in the direction of being standardized with just one single CSS approach. Unfortunately, that’s far away at the moment, and this is our option for now (CSS-wise).

    Remy,

    That’s kind of a huge discussion, but I’d say design (e.g. gradients) is extremely useful in teems of creating a better user experience, proven by Apple with a lot of their products.

    With IE and performance on filters, absolutely, it’s a valid question and in the end it comes down to testing and evaluating the experience for your specific use case.

    And yes, I’d love test cases deeply evaluating filters performance in IE as well.

  • #40 Andreas
    April 8th, 2010 at 22:57

    http://gradients.glrzad.com/ nice css3 gradient generator, doesnt support ie filters though. probably because its not css3 :)

  • #41 Robert Nyman - author
    April 8th, 2010 at 23:01

    Andreas,

    Nice, thanks for the tip!

  • #42 ruvan
    April 14th, 2010 at 14:45

    i’m think you have knowingly ignored opera simply because there is no CSS way other than using the newer HTML5 canvas.

  • #43 Robert Nyman - author
    April 14th, 2010 at 16:11

    ruvan,

    Yes, it was an unfortunate word choice.

  • #44 Francis
    May 13th, 2010 at 1:35

    nice work, only to let you know the gradient does not work in firefox on linux :o )

    hope FF will do something for that soon.

  • #45 Robert Nyman - author
    May 13th, 2010 at 21:42

    Francis,

    Really? Can’t check right now, but if that’s the case, it’s not good.

  • #46 bit
    May 19th, 2010 at 1:56

    I’m pretty sure I saw an effect like radial gradient in IE.

    Also, quit whining in the comments people! These CSS properties are EXPIRAMENTAL (exculuding IEs old stuff of course). They are still drafts on w3.org, meaning they are still even subject to change. browsers that did implement them already used a prefix for the purpose of marking them as expiramental.
    And its a good thing too, because if they hadn’t a lot of websites will be broken when CSS3 would actually be finished, just because you guys only read misinforming blog posts for information instead of the offical specification/browser release notes.

    And another thing, whats wrong with multiple HTTP requests? How is it a bad thing to devide content into different files that load individually, giving the user the option to stop, block, and or manipulate certain downloads in a page? Do you think a few bytes of HTTP headers are going to slow down your page loading time considerably? I guarantee you that your favorite JS library, that has functions you never use — and still load on every page, does a lot more damage to your loading time than than a few HTTP requests.

  • #47 Robert Nyman - author
    May 19th, 2010 at 9:26

    bit,

    If you know about the radial gradient in IE, please let me know!

    Regarding the number of HTTP requests, lots and extensive research by, for instance, performance guru Steve Souders (formerly of Yahoo!, now with Google) and by Yahoo!, described in Best Practices for Speeding Up Your Web Site, shows that too many HTTP requests is one of the biggest performance problem on the web. It’s about superfluous header data, latency etc.

  • #48 bit
    May 19th, 2010 at 15:22

    Here’s a typical example of some http headers, taken from this pages’ request:

    Date: Wed, 19 May 2010 12:49:15 GMT
    Server: Apache/2.0.54
    X-Powered-By: PHP/5.2.6
    Vary: Cookie,Accept-Encoding
    X-Pingback: http://robertnyman.com/xmlrpc.php
    WP-Super-Cache: WP-Cache
    Content-Encoding: gzip
    Content-Length: 24640
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Content-Type: text/html; charset=UTF-8

    200 OK

    The concept of HTTP headers was created for a purpose, it wasn’t created to slow things down.

    Lets take a simple real-world case where headers can help speed things up:
    A user might tell a browser not to load an image if its bigger than, say 10kb. Or even, a browser might prioritize its requests differently and load the bigger images last. The browser will need the Content-Length header to know what the image size is in order to make these decisions.

    The size of the HTTP headers above is 339 bytes. 339 bytes people!
    Lets compare it to something useless that I see on most webpages today; redundant jQuery functions. e.g. .animate(). You don’t always use .animate() in your project, but you always include it. Why? because its comfortable to know its there when you need it, because its hard to build your own custom version of jQuery. Who pays the price? Your users.

    That function is about 1.9kb in size, uncompressed, unpacked. I have no idea how much space it actually takes on the compressed and packed version of jQuery, but I’m sure its much more than a few bytes.

    Conclusion — Before you run off into the sunset with some “genius” from Yahoo/Google, do your own research, use logic. You want to speed up your website? There is plenty of bad coding in things like JS libraries that you can tweak before you decide it’s time to break/cheat the browsers’ function.

    <food-for-thought>

  • #49 Robert Nyman - author
    May 19th, 2010 at 16:52

    bit,

    I’m not defending the size and number of superfluous functions in JavaScript libraries at all, and I agree they’re overused.

    However, this research is performed by a lot of people working for the highest trafficked web sites on the Internet, and it is common knowledge that a huge number of HTTP Requests affects performance poorly.

    Regarding images: if you want even better performance there, base64-encode your images, resulting in no extra request and the possibility to gzip the output as well.

    The biggest problems with HTTP Requests isn’t header size, it’s about latency and limited number of concurrent downloads in web browsers.

  • #50 bit
    May 20th, 2010 at 1:04

    Alright, I can see how multiple images in a website might be a problem if you’re using a lot of images and the browser limits the amount it will download at the same time.

    However, it should only be used if your website has a lot of images. Because it is useful to devide images into different files, and because semantically, background-image was only intended for backgrounds.

  • #51 Robert Nyman - author
    May 20th, 2010 at 10:43

    bit,

    I agree, you do need to adapt to your context needs, there’s no solution fits all.

  • #52 Wait till I come! » Rimshots for all – using HTML5 audio and CSS3 to make instantrimshot.com
    May 23rd, 2010 at 11:17

    [...] the background for my work I used HTML5Doctor’s Audio in the browser article and Robert Nyman’s CSS gradient example and I have to say a few things about [...]

  • #53 Start Using CSS3 Today: Techniques and Tutorials | Web Design Cool
    June 17th, 2010 at 15:23

    [...] CSS Gradients For All Web Browsers, Without Using ImagesRobert Nyman explains how to code cross-browser CSS gradients that work even in Internet Explorer. [...]

  • #54 Start Using CSS3 Today: Techniques and Tutorials | ZoooZu.com
    June 23rd, 2010 at 2:07

    [...] CSS Gradients For All Web Browsers, Without Using Images Robert Nyman explains how to code cross-browser CSS gradients that work even in Internet Explorer. [...]

  • #55 Manish Kosta
    July 19th, 2010 at 13:27

    google crome does not run this efficient as a hight of gradient effect

Write a comment

Twitter reactions

Share your thoughts:

HTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> . If you want to display code examples, please remember to write &lt; for < and &gt; for >.

Comment preview