CSS3 and Gradients

Written Aug 25, 2011. Updated April 29, 2012

This introduces the gradient editor I began work on in the summer of 2010. I am pretty sure I was the first crazy enough to write such a tool and that it’s the only one in existence to date.

Yes, I know many gradient tools have been out there for years - some pretty slick ones. But mine is the first that lets you design a multicolored (more than 2), multidirectional (like the one here on the right) that will look the same in all browsers. that looks consistent in all browsers. Try viewing this page in IE6, Opera, Firefox, or Chrome as proof.

The draft of the w3c as of August 2011 contains clear recommendations for linear gradients. They even have radial and repeating gradients; however, truly considering writing a tool that implements both of those is a tad frightening. Just getting the linear gradients working is hard enough.

But what the w3c publishes and what the browsers decide to implement are often 5 different things. And in this case, 5 is the magic number. Who knew making rainbows was so hard to agree on? Here are the various implementation references for gradients.

  1. CSS gradients in Webkit (Chrome/Safari)
  2. CSS gradients in Gecko (Firefox)
  3. VML gradients in Trident (Internet Explorer) and 2-color CSS (DXTransform) gradients in Trident (Internet Explorer)
  4. CSS gradients in Opera
  5. The w3c working draft for linear gradients

Now here is how the above gradient is expressed for the different browser flavors.

<style type=text/css>
.gradient-sample1{
  /* http://thewebkid.com/gradients/#0.326,0.000+0=37,129,127,1+
0.279=239,111,50,1+0.46=246,18,10,1+0.757=68,0,49,1+1=45,14,177,1 */
	/* Chrome/Safari */
	background:-webkit-gradient(linear, 
		32.6% 0%, 67.4% 100%,
		color-stop(0, rgba(37,129,127,1)),
		color-stop(0.279, rgba(239,111,50,1)),
		color-stop(0.46, rgba(246,18,10,1)),
		color-stop(0.757, rgba(68,0,49,1)),
		color-stop(1, rgba(45,14,177,1))
	);
	/* Firefox */
	background:-moz-linear-gradient(
		32.6% 0%,
		rgba(37,129,127,1) 0%,
		rgba(239,111,50,1) 27.9%,
		rgba(246,18,10,1) 46%,
		rgba(68,0,49,1) 75.7%,
		rgba(45,14,177,1) 100%
	);
	/* Opera */
	background:-o-linear-gradient(289.2deg,
		rgba(37,129,127,1) 0%,
		rgba(239,111,50,1) 27.9%,
		rgba(246,18,10,1) 46%,
		rgba(68,0,49,1) 75.7%,
		rgba(45,14,177,1) 100%
	);
	/* IE 6-9 */
	behavior:url(/scripts/iegradient.htc);
	filter:progid:DXImageTransform.Microsoft.ICMFilter(
		colorSpace="289.2|0 #25817f,0.279 #ef6f32,0.46 #f6120a,0.757 #440031,1 #2d0eb1");
}
</style>

The syntactical differences between Opera, Firefox, and Chrome are minor, but enough to drive a web designer crazy. What designer could try to create gradient themes with the patience to figure out how to write the CSS on even ONE browser? Clearly someone needed to write a tool.

I considered writing a common tool that worked for Chrome and Firefox as my first task. I have had a fascination with colors and programming for virtually my entire web development career (since 1998). I have written some other components - most notably the color picker control. So the next logical step was to take various related components (move, sliders, colorpickers, and some utility functions) and put them on a page together to create a gradient tool.

Those of you with experience in gradients may be wondering how Internet Explorer is rendering a 5-color gradient at a 289.1 degree angle. Did we all just miss the ICMFilter(ColorSpace="") and this webkid guy found it or knows some super secret ninja gradient syntax he got from having drinks one night with the Internet Explorer program manager?

I wish.

Actually... the secret to this is... drum roll...

Vector Markup Language - everyone's favorite Microsoft rendering technology, right?!

But why VML and not Canvas or SVG?

Basically legacy support. I am pretty sure IE5 will render this control. I know IE 6+ will. But, were I to use canvas, I would lose all that delicious backward compatibility.

Ok, so what does the ICMFilter have to do with rendering a gradient OR with VML? Well in short - nothing. But it WAS a place I could encode gradient information that was part of a stylesheet. ColorSpace expects a URI, so I tried putting a gradient string there and then reading that string from within a behavior in order to make it a shoe in for a designer to create a gradient. No fancy expando attributes to hack into the element. No script calls. No JSON, just a wonky lookin CSS string that you can copy/paste into a style declaration.

So how does it work? Sadly, the one drawback to my solution is that you must have JavaScript enabled in IE and you need to download the iegradient.htc behavior file and reference it in your style declaration. Almost a pure CSS implementation. So close :)

I hope this tool is useful to you. I would love to hear feedback.