Update!
I have a much more elegant solution to this problem.
The Problem
Internet Explorer 9 beta supports CSS3 rounded corners with the border-radius property.
Internet Explorer 9 beta does not support CSS3 gradients but continues to support the legacy, proprietary, gradient filter for creating gradient backgrounds on html elements.
Unfortunately, the two do not work together. Applying a gradient filter to an element with rounded corners results in the gradient background poking through the borders of the element. Here is a screen shot of the bug in action.

Fortunately, though, there is a workaround.
The Solution rhymes with SVG
If you don’t need rounded boxes with gradient backgrounds, then you don’t have a problem.
Tools like the Ultimate CSS Gradient Generator generate the code needed for lovely CSS3 gradients with a fallback option for legacy Internet Explorer (using the gradient filter mentioned above).
This generated CSS is almost perfect ‘out of the box’ and can be relied upon for Safari, Firefox, Chrome, and all versions of Internet Explorer.
However to fix the IE9 problem above, we need to look to other new features of IE9.
- SVG background-image support
- support of the background-size CSS3 property
And some old favorites.
- conditional comments
- image sprites with background image positioning
IE9 has broad support for SVG images, including the use of an SVG image as a background image. This means you can specify an SVG image just as you would any background image in your CSS.
background-image: url(gradients.svg);
The ‘S’ in SVG stands for ‘scalable’ – any SVG image used as a background image can scale to any dimension in your web page. For background images this is handled explicitly by the CSS3 background-size property.
background-size: 100% 100%;
The snippit above tells the browser to scale a background image to 100% of the width and 100% of the height of the html element. As far as IE9 is concerned, the SVG image (gradients and all), is just the same as any other image. So, it plays nicely with other CSS3 features like border-radius and box-shadow. It’s easy now to imagine creating an SVG file for every background we need to fix:
IE 9 will try to render the legacy gradient using the filter property above, so we need to instruct IE9 specifically to ignore that rule, with a style block within a conditional-comment.
<!--[if ie 9]>
<style type="text/css" media="screen">
.round-gradient-box
{
filter: none;
}
</style>
<![endif]-->
And finally we need an SVG image to replace the gradient:
If your browser supports SVG, you can view it here.
In the example SVG above, you will note that the SVG object has a specific size – 500 x 500. Your SVG files need an intrinsic size so IE can tile them into the background. If you use a percentage value, tiling may not work properly.
Here’s an example of everything together.
If you have only one or two gradients to support, the above approach will work just fine. However, if you are working on a large site or application with lots of custom interface elements, editing individual SVG files is going to become hard to manage.
Obviously it would be nice to consolidate all your gradients into a single fileā¦
SVG Gradient Sprite Backgrounds
The above SVG file has one gradient definition and one rectangle element which uses the defined gradient as its fill. Obviously we can create as many as we want in order to create a gradient background sprite.
It’s common for web designers to tile several images into a single file – a sprite – and use this same file over and over again displaying different parts where needed.
The same concept can be applied to an SVG background image as well, but with an important difference. SVG images can scale indefinitely.
A single, small, SVG file can define dozens of gradients which can be applied to page elements, form elements, whatever, and they will always scale to fit. Yeehaw.
Here is a run down of how this will work.
- Define CSS3 gradients with a fallback to legacy IE gradient filters
- Create an SVG with the same gradient styles
- In IE9 only, display the gradient SVG background image, scaled and positioned as needed
Here is an SVG file with 5 gradients defined
<!-- background gradients -->
<!-- 0% -->
<!-- 20% -->
<!-- 40% -->
<!-- 60% -->
<!-- 80% -->
If your browser supports SVG you can view the file here.
This SVG file defines 5 gradients, and 5 rectangles using the gradients as fills. Each rectangle is 100 pixels square, and arranged vertically, each rectangle below the last. The total height of the graphic is 500px.
The specific size of the rectangles is not technically important – however, using dimensions that are large enough to see is handy for previewing, and nice round numbers are easier to work with. Larger sizes will not make the file bigger. You do need to define the width and height of the SVG file, otherwise the image will not scale correctly.
The gradients defined in this SVG file match CSS3 gradients defined in this example page.
We want each gradient to fill the vertical height of each box we are styling. Each gradient section is of equal height, and there are 5 sections. So in a style block within a conditional comment targeting IE9, we specify the background image as the SVG, and set the background-size property to scale the vertical height of the graphic to 500%.
background-image: url(gradients.svg); background-size: 100% 500%; /* horz vert */
Why 500%?
Each section of the graphic – each gradient box – should be 100% of the height of any element it is applied to. Since there are 5 total gradient sections, 500% / 5 = 100%. If you define 10 gradients, use 1000%, if you define 20 use 2000%. (this is why we want nice round numbers.)
If you look at the HTML source of the example page you ‘ll see that a CSS class is defined for each gradient background. The class definitions include a standard CSS3 gradient definition, and as well a background-position property set to position the background gradient SVG image to the right place.
Since the first gradient definition with the CSS class of “info” is at the top, it’s easy.
background-position: 0 0;
The background starts at the top-left corner of the box, so there’s nothing to adjust.
Likewise, the last one in the list is easy to do as well.
background-position: 0 100%;
It’s at the bottom of the stack of gradients, so we position it at 100%. Done.
How do we get the percentages for the middle ones?
Percentage position calculations for CSS background images are kind of weird and counter-intuitive, and too much to get into here. So for the purposes of this exercise just use the following handy formula, where ‘n’ is the number of gradients in my file:
base percentage = 100% / (n-1)
If you have 5 gradients, that would be 100% / (5 -1) or 100% / 4 or 25%. We subtract one, because we start measuring pixels at zero. To get the percentage for each gradient, multiply the base percentage times the number of the gradient.
If our first gradient is zero, 0 * 25% is 0. Duh. 1 * 25% = 25%, 2 * 25% = 50%, etc. If you want to count like a human, count from one, and subtract the base percentage: (1 * 25%) – 25%, (2 * 25%) – 25%, (3 * 25%) – 25%, (4 * 25%) – 25%, (5 * 25%) – 25%
This would work the same for 6 gradients as well.
100% / (6-1) = 100% / 5 = 20%
Giving you vertical percentages of 0, 20, 40, 60, 80, and 100.
If you have a wonky number of gradients, you’ll end up with a decimal percentage. That’s not only sloppy, but could result in a rounding error in IE9, which causes your gradient to be positioned slightly off. Therefore it’s best to use numbers which divide into 100 evenly.
If you have an odd number of gradients, simply pad the height of your SVG. For example, if you have 7 gradients, make your SVG 11 times as tall as a single gradient, and leave the remaining slots empty. That way you have room for 4 more gradients, and the math is easy:
100% / (11 - 1) = 100% / 10% = 10%
This technique should work for elements of any height and play nicely with JavaScript extensions of legacy Internet Explorer like PIE and IECSS3.js
Drawbacks
It takes a good deal of extra work to create the SVG file along side standard CSS3 gradient declarations. Given your needs it maybe wiser just to create individual SVG graphics for IE, use traditional background images, or simply use flat colors if rounded corners are required.
Sometimes, due to percentage rounding, a gradient may be very slightly misaligned. This can be fudged by changing the height of the element in question, or adjusting the vertical background position percentage slightly. Consider using fixed heights on troublesome elements or simply by creating a custom background for that element.
Share and enjoy!