”Chroma Corners”

A Rounded Corners Technique for Legacy IEs

Rounded corners and the Internet Explorers is a nuisance that has accompanied us for some years now. In recent time that topic lost some of its momentum as we successfully engineered a handful of approaches to get the problem solved.

Still, all solutions at our disposal have each their own drawbacks: one completely ignores IE (”graceful degradation”), one is inflexible (single background-image), anotherone restricts your freedom of design (”Mountaintop Corners”), the third one needs a lot of photoshopping action (”Sliding Doors”), and the last one lowers compatibility and rendering performance considerably (CSS3 PIE).

Are those techniques the best we can ever get?

No, they're not!

Not too long ago I had a quite tranquil day that I used to work on new CSS techniques. I also played around with how one could build better rounded corners when I suddenly remembered a demo I saw some time ago.

The demo in question is already three and a half years old and shows a technique on how to fake an interactive 3D object in the browser with the help of HTML elements with special border properties set.

One major trick is to make borders disappear and what caught me was how the author had them vanish in IE 6 which does not know a border-color value of transparent. The guy gave the border he wanted to vanish a certain color and then applied IE's proprietary chroma filter to the corresponding element, with its keying color set to that border color.

How the Chroma Filter works

What the chroma filter does is comparable to the filmmaker's bluebox / greenscreen technique: it makes all parts of an element in a certain color vanish from the screen. The color is used as a mask.

The following CSS code for example lets disappear all cyan colored parts of an element:

filter: progid:DXImageTransform.Microsoft.Chroma(color='cyan'); /* IE 6/7 Syntax */
-ms-filter: "progid:DXImageTransform.Microsoft.Chroma(color='cyan')"; /* IE 8 Syntax */

One could also write #00FFFF instead of cyan. Why chose cyan? Well this is probably the one color that nobody would never ever use to colorize anything. Still, you are not bound to cyan, you are free to use any color you like as key color.

Now, what's even more interesting with the chroma filter is the fact that not only do cyan colored parts from the element itself affect the area of masking, but also do cyan colored parts of the element's children. Because of this one could create some sort of 10px thick frame by applying the following CSS…

.foo {
	width: 120px;
	background-color: #EEE;
	filter: progid:DXImageTransform.Microsoft.Chroma(color='cyan'); /* IE 6/7 Syntax */
	-ms-filter: "progid:DXImageTransform.Microsoft.Chroma(color='cyan')"; /* IE 8 Syntax */
.bar {
	height: 100px;
	margin: 10px;
	background-color: cyan;

…to this markup:

<div class="foo">
	<div class="bar"></div>

The area of the child element .bar would be punched out of the filter bearing parent element .foo and we could look through it.

red frame made with IE's chroma filter

And of course chroma also works for background images containing the key color!

So, coming to our brand new rounded corners solution we go and create an image file with the dimensions 2048 × 2048 pixels (which seem to be IE's maximum image size). We leave all of that image's background transparent and we just fill the outside shapes of the rounded corners with our key color (cyan). Then we save it as 8 bit GIF or PNG with transparency.

creating the background image

Then we go into our HTML and create the following markup for our element which will have the rounded corners…

<div class="chroma_base">  	
	<div class="chroma_topleft">  		
		<div class="chroma_topright">  			
			<div class="chroma_bottomright">  				
				<div class="chroma_bottomleft">Drag me!</div>  			

… having as many child elements as we need rounded corners, in this case four. To all four we assign our freshly created background image – with a different alignment for each one:

.chroma_bottomleft {
	background-image: url(chroma14px.gif);
	background-color: transparent;
	background-repeat: no-repeat;
.chroma_topleft {background-position: left top;}
.chroma_topright {background-position: right top;}
.chroma_bottomright {background-position: right bottom;}
.chroma_bottomleft {background-position: left bottom;}

Side note: the above styles are not suited for browsers other than IE 8 or less, so put them into Conditional Comments or something. Using a single image for all corners helps reduce HTTP-requests.

Our current state is now this (right side darkened for better visual contrast):

Chroma Corners

Our root element named .chroma_base now gets the chroma filter, and all the other styles that shall affect the appearance of the object:

.chroma_base {
	position: relative; /* Needed for IE 6/7 */
	top: 150px;
	left: 150px;
	width: 200px;
	line-height: 50px;
	text-align: center;
	background: #600118 url(gradientdark.png) repeat-x left top;
	color: #FFF;
	zoom: 1; /* Needed for IE 6/7 */

	-moz-border-radius: 14px;
	-webkit-border-radius: 14px;
	border-radius: 14px;

	filter: progid:DXImageTransform.Microsoft.Chroma(color='cyan'); /* IE 6/7 Syntax */
	-ms-filter: "progid:DXImageTransform.Microsoft.Chroma(color='cyan')"; /* IE 8 Syntax */

And we are done! This is the result:

floating element with rounded corners

The nice thing about it: you can at any time not only change the element's colors and background, but also the background area's without need to rework the chroma background image for this!

Should your design make use of rounded corners everywhere all with the same radius then you can use this single chroma background for every one of those rounded corners elements.

And of course the solution works with textured element background and a textured background area!

What's with Solid Borders? Will This Work with Border Outlines?

Yes, it does!

But it needs a little more work, is a little less robust and also removes a some flexibility. This is how it goes: First we need to modify our element's background image back in Photoshop by adding the border in its appropriate width and color to the inner corner radii:

adding a solid border to the corners

The example above shows a border of 2px width colored in #808080. Second, we need to add the following styles to the root element:

.chroma_base {
	border: #808080 2px solid;

Because we need our children's background image to overlap that CSS border we add…

.chroma_topleft {
	margin: -2px; /* root border-width * (-1) */

… only for IE 8 and older (use Conditional Comments again), and on top for IE 6 and 7 we need…

.chroma_base * {
	position: relative; /* Needed so that border overlaping works in IE 6/7 */
	width: 204px; /* root width + (2 * root border-width) */
	height: auto; /* if root has height set, assign: root height + (2 * root border-width) */

Side note: IE 6 and 7 don't seem to be able to overlap a parent element on all four sides if you just specify width: auto; margin: -2px;. That's why we need to specify this fixed width when using borders. For height this is only needed if the .chroma_base-element has a height assigned.

Done! Together with a brighter background image we now have this result:

floating element with rounded corners and borders

We still have all most advantages present of the borderless version, with the following differences:

  1. We are not very flexible when it comes to changing the appearance of the border. As soon as its thickness or colors needs to change we need to go back into Photoshop.
  2. When using solid borders we absolutely need to specify fixed width in order to have it work in IE 6 and 7.

The name of the beast? I call it the ”Chroma Corners”. I've put an example online for you here to play around with and I also put online a IE-behavior that will do all the dirty work for you. Have fun with it!

Christian ”Schepp” SchaeferChristian ”Schepp” Schaefer is a freelance web developer living in Düsseldorf, Germany. He is the author of CSS-JS-Booster and co-author of Turbine CSS Framework and follows your tweets under his account derSchepp.