An Experiment in Rounded Corners

An idea had struck me this afternoon that there might be some technology deep in the depths of Internet Explorer that might unlock the secret to easy rounded corners. Unfortunately, my initial idea fell flat and I was left in the same place I was before. However, bouncing from idea to idea, I thought to try VML. VML is an XML-based approach that Microsoft came up with and proposed it to the W3C. Alas, the proposal never went anywhere but that's neither here nor there.

The syntax to enabling VML is really clunky. You have to define a behavior for VML elements, include the VML namespace and then use the VML syntax. Is it any wonder this didn't capture the hearts of web developers everywhere?

Here is the following code that includes the VML namespace and declares a v prefix to be used for all VML elements.


<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />

VML has support for rounded rectangles using the roundrect element. Here's the basic syntax I've put together including some basic content. Note the v: prefix.

<v:roundrect arcsize=".02" fillcolor="#000">
Lorem ipsum dolor sit amet, consectetuer adipiscing 
</v:roundrect>

The rounded rectangle has a number of properties, of which the arcsize and the fillcolor are defined here. Unfortunately, I know of no way to declare the fill color via CSS which will leave you defining fill color in two separate places. If you wish to use a background image, you'll need to look into the fill VML element.

The arcsize is relative to the element size, which is unfortunate since box sizes may differ. If your box sizes tend to be around the same size, or you don't mind a little variety, then you could probably set an arcsize without worrying about it too much.

Finally, we need some CSS to enable the VML:

v\:roundrect  {
    behavior:url(#default#VML);
    }

Next, let's style this element up for the rest of the browsers (with a little extra for IE to play nice).

v\:roundrect {
    color:#FFF;
    display:block;
    background-color:#000;
    -moz-border-radius:10px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
    padding:20px;
    height:100%;
    
    /* IE-specific */
    behavior:url(#default#VML);
    /background-color:transparent;
    }

The font color has been defined and the element is set to display:block for all browsers to recognize this unusual element as such. Border-radius gives it that rounded magic. And most importantly, I've used an IE hack to turn the background color off. Otherwise, you'd get a rounded black box on a square black box. In other words, just a square box.

(Feel free to move the hack into its own file via conditional comments, I've only used the hack here to be concise. Although, this disclaimer has destroyed that brevity, but I digress).

Why?

While this "works", it feels so wrong. I wouldn't want to whip this out on a client project. I think it would confuse anybody left in charge to maintain it. Although, the slightly more relevant presentational semantics of wrapping rounded elements with roundrect is almost as slightly enticing—that is, until you decided to square off all containers. Anyways, I digress again.

In any case, this is just that: an experiment. To point out that it could theoretically be done if you felt like it.

One final note, this won't work in IE8 beta 1 but should work in everything from IE5 through IE7.

Feel free to check out the demo page.

Published August 18, 2008
Categorized as HTML and CSS
Short URL: https://snook.ca/s/905

Conversation

30 Comments · RSS feed
Bill said on August 18, 2008

Very interesting post. I've been looking for a fairly quick & easy way to do rounded corners, not sure this is it but definitely worth exploring.

Damien said on August 18, 2008

You're right, that is a very awkward solution. The nearest comparison I can think of is using SVG's within FireFox to fake -mox-border-radius.

Here's hoping for CSS3 and HTML5 to be put into standard use before we retire. :D

Lim Chee Aun said on August 18, 2008

This is cool, but can you whip up a testcase page for the examples?

Jonathan Snook said on August 18, 2008

@Lim Chee Aun: I've now linked up a demo page.

Lim Chee Aun said on August 18, 2008

Thanks, Jon. I wonder if this can be done via Javascript to create the VML elements, replacing div's that require rounded corners and display them only on IE.

Damjan Mozetič said on August 18, 2008

While such browser-specific features should probably never see the light of the real world, they are still nice to see implemented by somebody. This should be handed over for standardization methinks :)

sfpavel said on August 19, 2008

the code is not valid. I'd rather use only the moz specs on a div, or images of the corners for a fluid design, or just normal css for a fixed width design

Marin said on August 19, 2008

I was just looking at this yesterday. Meaning I was trying to get the most cross-browser lightest code for those rounded corner. Using the -moz-border-radius, the -webkit-border radius, the svg background for Opera.

I'll have a look on how that VML could fit in a real world situation (floated/absolute positionning etc...).

Nikita Vasilyev said on August 19, 2008

Crossbrowser solution. I added some SVG for Opera.

Frank said on August 19, 2008

Wow, that is very interesting - how do people stumble across stuff like this?

@Nikita cheers for that link

Andy Kant said on August 19, 2008

To be honest, if someone were going to the trouble of adding a bunch of extra DOM nodes just to get rounded corners, I think that this would definitely be a better solution. I would agree that having a non-standard element in my markup would make me uneasy though (unless its injected at runtime in IE, at which point you kinda lose what you gain in simplicity from this technique). I'm not really into to the whole rounded corners fad anyways though, prefer to keep it stylized like your site.

Ash Searle said on August 19, 2008

Google Maps relies on VML too, which is why they suggest adding the VML namespace to any page embedding one. Their suggestion is a bit simpler, as it's just an additional attribute on the <htmL> tag:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" ...>

See http://code.google.com/apis/maps/documentation/#XHTML_and_VML

Alexei said on August 20, 2008

Great, FF supports this code too.

Fredrik W said on August 20, 2008

To all the people complaining about "invalid code" -- it's not. XHTML allows you to embedd other XML namespaces and use them with a prefix, just as being done here.

Rogie said on August 20, 2008

I love that you are curious Jonathan. Pretty inventive solution. The only thing that always majorly sucks with this, even when loaded with JavaScript is Firefox 2's lousy -moz-border-radius implementation.

Awesome tinkering. Thanks for sharing.

Daniel said on August 20, 2008

Nice, I've played with VML awhile back thanks for the reminder of its capabilities.

micha said on August 20, 2008

i've tried to automate this with some basic js.
here's my demo: http://pixelficker.com/lab/corners/

some problems with opera and IE7 though. couldn't test IE6.

any thoughts ?

Mark Story said on August 21, 2008

Very nice work Jonathan. The result is a bit awkward, but if the elements were swapped in by javascript or conditional comments it could be a very clean technique.

Jonathan Snook said on August 21, 2008

Thanks Mark. I've been mulling it over and I'd be interested if I could do the same using an htc behavior. In this way, it would be nice to parse the currentStyle on the element, then replace it while applying those styles on the new element. But that experiment is for another day when I have more time. :)

Étienne said on August 27, 2008

This should prove very practical, thank you.

Levi said on September 01, 2008

Excellent investigation, Jonathan! I've wrapped your work into a JQuery Plugin. This should help avoid the hassle of all the platform checking.

http://jcorners.culturezoo.com/

There's probably some bugs, but I've installed it on my site and it seems to be working. Let me know what you think.

WD Milner said on September 10, 2008

Interesting, in some ways simpler in others more complicated than images and such. I have a small site redesign coming up and may try this out. Thanks for this!

Joseph said on September 28, 2008

Hey , I was just searching the web and actually looking for something else BUT here is how I do my rounded corners and it works in ALL BROWSERS

Here it is:

####### style ##########

.xtop, .xbottom {display:block; background:transparent; font-size:1px;}
.xb1, .xb2, .xb3, .xb4 {display:block; overflow:hidden;}
.xb1, .xb2, .xb3 {height:1px;}
.xb2, .xb3, .xb4 {}
.xb1 {margin:0 5px; }
.xb2 {margin:0 3px; border-width:0 2px;}
.xb3 {margin:0 2px;}
.xb4 {height:2px; margin:0 1px;}

.xboxcontent {display:block; background:#FFFFFF; padding: 5px 5px 5px 5px}
#################################

Wrap This


<div class="xboxcontent">

YOUR CONTENT HERE

</div>

</div>

Hope you guys enjoy!

See ya

Joe

Dave said on October 01, 2008

Sounds interesting, i'll try it the next time i need rounded corners.

Thomas said on October 17, 2008

Respect! But indeed, there might be, or come a better way. I know that there is already a jQuery plugin for rounded corners. And I guess it's also supported in css3.

Andrew Hypnosis said on November 02, 2008

It definitely seems to work in IE7.

Chris said on December 04, 2008

Seems to work well in IE6 and Safari. Surprising.

Dale Larsen said on December 17, 2008

Want to this see this working with flying colors?!

Drew Diller pulled it off.

Check it out:
Click here

Anonymous said on March 18, 2011

The solution is good. but i was looking for a way to make buttons on my page with round corners without using any images. Is it possible for IE6 on XP with disabled theme?

BruceCH said on March 18, 2011

This is an old thread, but I was playing around with something similar(border-radius.htc) and after many hours of pulling out what little hair I have left, I discovered why my implementation wasn't working. VML doesn't work with MS gradient filters! If there is a gradient filter on an object, you get no viewable VML. Bummer.

Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.