Tuesday, July 28th, 2009

CSS Gradients for All!

Category: CSS

Weston Ruter has created a very cool library that enables CSS gradients on non-WebKit browsers (at least, a subset). Incredibly cool:

CSS Gradients via Canvas provides a subset of WebKit’s CSS Gradients proposal for browsers that implement the HTML5 canvas element.

To use, just include css-gradients-via-canvas.js (12KB) anywhere on the page (see examples below). Unlike WebKit, this implementation does not currently allow gradients to be used for border images, list bullets, or generated content. The script employs document.querySelectorAll()—it has no external dependencies if this function is implemented; otherwise, it looks for the presence of jQuery, Prototype, or Sizzle to provide selector-querying functionality.

The implementation works in Firefox 2/3+ and Opera 9.64 (at least). Safari and Chrome have native support for CSS Gradients since they use WebKit, as already mentiond.

This implementation does not work in Internet Explorer since IE does not support Canvas, although IE8 does support the data: URI scheme, which is a prerequisite (see support detection method). When/if Gears’s Canvas API fully implements the HTML5 canvas specification, then this implementation should be tweakable to work in IE8. In the mean time, rudimentary gradients may be achieved in IE by means of its non-standard gradient filter.

CSS Gradients via Canvas works by parsing all stylesheets upon page load (DOMContentLoaded), and searches for all instances of CSS gradients being used as background images. The source code for the external stylesheets is loaded via XMLHttpRequest—ensure that they are cached by serving them with a far-future Expires header to avoid extra HTTP traffic.

The CSS selector associated with the gradient background image property is used to query all elements on the page; for each of the selected elements, a canvas is created of the same size as the element’s dimensions, and the specified gradients are drawn onto that canvas. Thereafter, the gradient image is retrieved via canvas.toDataURL() and this data is supplied as the background-image for the element.

An aside. I only just noticed the Gears Canvas API. It doesn’t quite do what you think….. I always wanted to implement Canvas in Gears. It is also strange that Gears is so under the radar at Google these days. One blog post per year?. I guess all of the work is going into Chrome / WebKit itself.

Posted by Dion Almaer at 6:00 am

2.9 rating from 32 votes


Comments feed TrackBack URI

Indeed this is “Incredibly cool”, thanks for the article.

Comment by stoimen — July 28, 2009

I’d like to have sth like (-moz-)gradient: … ; It’s kinda idiotic to place css statements like this:
-moz-border-radius: …;
-webkit-border-radius: …;
border-radius: …;

how this will end? -opera, -moz, -webkit, -ie ?

Comment by gossi — July 28, 2009

Totally agree with gossi.

Comment by lunatic77 — July 28, 2009

I agree that IE sucks but ultimately it’s a reality that we’re all stuck with. Canvas widgets are cool but ultimately useless in the business world due to lack of browser support.

Comment by otatop — July 28, 2009


A correction: Opera’s prefix is -o- and Microsoft’s prefix is -ms-. FunPackedShow’s answer about prefixes is right, too.

Comment by eyelidlessness — July 28, 2009

ah cool. I never make use by one of them, didnt even know they got them, that’s why I use those to express what I mean ;)

funpacked: Yes, I understand the reason and it makes sense to me. But does it also make sense to triple our work?

Comment by gossi — July 28, 2009

@gossi: A slight increase in work to prevent a huge increase in work due to possible compatibility issues? Yeah, makes sense.

Comment by MattCoz — July 28, 2009


The -ms- prefix is new in IE 8, and I doubt most people have used it. But I think in “real” standards mode, all of their CSS extensions now require the prefix.

As far as duplicating work… any decent IDE or decent editor should be configurable to auto-complete that stuff. For instance, in TextMate I type opacity[tab][decimal] and the result is:

opacity: [decimal];
-moz-opacity: [decimal];
filter:alpha(opacity=[decimal * 100]);

Bandwidth is a greater concern than keystrokes, in my opinion, but really it should be negligible with good structure.

As MattCoz says, the alternative is worse. The prefix solution is the standards recommendation for early implementation and extension of CSS, and it arose out of concern over the first “Browser Wars” where IE and Netscape continually introduced and broke CSS features, making CSS rules a moving target and CSS code unmaintainable and unreliable.

With the prefixes comes the ability to target different interpretations of unfinished standards and for the browser vendors to introduce features that can be, but haven’t yet been, standardized. Without them comes chaos, with the only benefit being a false sense of compactness.

Comment by eyelidlessness — July 28, 2009

@eyelidlessness: to make matters even worse MS has opted _not_ to implement “opacity” in IE8, but opted to require a vendor prefix on the proprietary “filter” which means IE now needs 2 lines instead of just one (doing the exact same stuff I presume):

opacity: [decimal];
-ms-filter:”progid:DXImageTransform.Microsoft.Alpha(Opacity=[decimal * 100])”;
filter:alpha(opacity=[decimal * 100]);

(As PPK explains on Quirksmode)


Comment by rasmusfl0e — July 28, 2009


Right. And come to think of it, I should update TextMate to reflect that.

Comment by eyelidlessness — July 28, 2009

ok matt, you got me :) IDE Templates is a good idea :)

Comment by gossi — July 28, 2009

@rasmusfl0e – I don’t understand what you mean, the standard filter seems to work in IE8 for me. I created a quick page with a big red block in it with an opacity of 25%.

This works in non-IE browsers:
opacity: .25;

This works in IE8, IE8 as IE7 and IE6 in Virtual XP Mode:
filter: alpha(opacity=25);

Or it does for me anyway. I don’t understand why it is said -ms-filter is required. Am I missing something?

Comment by travisalmand — July 29, 2009

travisalmand, the -ms- prefix and the full filter path (progid:DXImageTransform.Microsoft.Alpha) are required in IE 8’s “real” standards mode. They’re not required in “almost” standards mode or quirks mode.

Comment by eyelidlessness — July 29, 2009

Leave a comment

You must be logged in to post a comment.