bridge

Vector gradients from comp 1 to the browser

A few days before the official launch of Internet Explorer 9 I decided to take a look at the Traction website in the most recent IE9 release candidate. While we were developing the site it was still beta and CSS3 background gradients weren't supported. We were supporting them in IE7 and 8 via CSS3PIE but that didn't support 9. I decided to kick the can down the road and wait till the last minute just in case gradients magically became supported.

No dice apparently. IE9 still doesn't support background gradients. Some of our pages looked less than functional and I needed to fix that before the browser was released. The way I would have done it in the past (well, before the power and glory that is CSS3PIE) would be to use a gradient filter. But that's gone in IE9 as far as I know (correct me if I'm wrong). Luckily I found this technique. You basically use an SVG gradient as a background image. It worked like a charm.

<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" version="1.0" width="100%" height="100%" xmlns:xlink="http://www.w3.org/1999/xlink">
	<defs>
		<linearGradient id="contentGradient_IE9" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad">
			<stop offset="0%" stop-color="#bcbcbc" stop-opacity="1">
			<stop offset="40%" stop-color="#ffffff" stop-opacity="1">
		</linearGradient>
	</defs>
	<rect width="100%" height="100%" style="fill:url(#contentGradient_IE9);">
</svg>

The SVG color and stop values reminded me of CSS3.

.mainContent{
	background-image: url('/images/bg_mainContent_dots.png'), linear-gradient(left bottom, left top, color-stop(0.4, rgb(255,255,255)), color-stop(1, rgb(188,188,188)));
}

This got me thinking. What if I got the SVG of the gradient as part of the comps when they moved from design to dev? The SVG could be a smart object in Photoshop in the comps. When I get the SVG, I can take the color stop values, plug them into the CSS and get them exactly as the client saw them in the comps.

Currently a common way to work with gradients in Photoshop CS4 is to use a vector object then use a layer effect to add a gradient overlay. It's very simple to resize that box and not have to keep recreating gradients every time. Then the people building the thing reverse engineer the gradient stops and do some math to get percentage values. But that can take a while to get right and usually there's some trial and error to be done.

If you make these gradients this way you can make it a smart object but it's a different file format and when you double click to edit you don't get SVG in the export settings. And you can't just import an SVG, make it a smart object and save it later. In fact, you can't even open an SVG in Photoshop CS4.

What you can do is copy the vector path of a gradient in Illustrator, paste it in Photoshop and use that as a smart object.

To resize your gradient in Photoshop just select the layer the vector smart object is in and use the free transform tool.

If you want to change the gradient stops or color values, double click the layer and it will take you to Illustrator. Save your changes in Illustrator and when you go back to Photoshop the changes will take effect.

You still get the ability to edit gradients as vector objects just as if you had made a rectangle in a layer and used the gradient overlay layer effect. But now, when your design is "Final-esque" you double click the smart object and when it takes you to Illustrator you can save it out (Save As) as an SVG.

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="186.528px" height="221.243px" viewBox="0 0 186.528 221.243" enable-background="new 0 0 186.528 221.243"
	 xml:space="preserve">
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-17.3564" y1="110.6221" x2="203.8862" y2="110.6221" gradientTransform="matrix(0 1 -1 0 203.8862 17.3569)">
	<stop  offset="0" style="stop-color:#FFFFFF"/>
	<stop  offset="0.7975" style="stop-color:#4EB748"/>
</linearGradient>
<rect fill="url(#SVGID_1_)" width="186.528" height="221.243"/>
</svg>

That SVG doesn't look like what we need. For one we don't have percentage sizes which we need for it to scale to CSS box sizes and those matrices look like a ton of fun. So we edit it to get what we need.

<?xml version="1.0" ?>
<vg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" version="1.0" width="100%" height="100%" xmlns:xlink="http://www.w3.org/1999/xlink">
	<defs>
		<linearGradient id="myGradient" x1="0%" y1="0%" x2="0%" y2="100%" spreadMethod="pad">
			<stop offset="0%" style="stop-color:#FFFFFF" stop-opacity="1"/>
			<stop offset="80%" style="stop-color:#4EB748" stop-opacity="1"/>
		</linearGradient>
	</defs>
	<rect style="fill:url(#myGradient);" width="100%" height="100%"/>
</svg>

So, now we have our SVG file, our CSS and our PIE:

/* CSS3 */
.mySelector{
	background-image: linear-gradient(left bottom, left top, color-stop(0.8, #4EB748), color-stop(1, #ffffff));
}
<!--CSS3PIE for IE 8 or less-->
<!--[if lt IE 9]>
	<style type="text/css" media="screen">
		.mySelector{
			behavior: url(/css/PIE.htc);
			-pie-background: linear-gradient(center bottom,rgb(78,183,72) 80%,rgb(255,255,255) 100%);
		}
	</style>
<![endif]-->
<!-- SVG image background for IE9 -->
<!--[if IE 9]>
	<style type="text/css" media="screen">
		.mySelector{
			background: url('/images/my_svg.svg');
		}
	</style>
<![endif]-->

All of it is derived from the exact values that created the gradient in the comps. No guestimating. Designers still get the convenience of vector gradients. Developers get code out of a comp they can hack on instead of having to divine the one true gradient. And our gradients stay vectors from creative round one all the way to the users's screen. No banded or dithered raster gradients needed.

Tack Trudell Senior Technologist

I am an integrator of things. I look beyond front end, back end and the object to see where art and tech can manifest the whole.