Cross Browser Rounded Corners Using VML

Hopefully, your job does not have to support corporate customers whose IT departments do not keep the companies browsers up-to-date, and therefore do not need to support older version of IE. If however, like me, you need to support older IEs, then your companies designers have probably asked you to support rounded corners in IE.

The three most common techniques to solve rounded corners are to use JavaScript [1] or an HTC Access[2] file to produce VML (Vector Markup Language[5]) on demand, or a JavaScript solution that inserts positioned divs to emulate rounded corners[3]. However, all these solutions are slow (search the DOM for rounded elements on load or round on demand), kinda hacky, and require recalculations as rounded elements are repositioned.

The core of the first two strategies is to dynamically inject VML into the document using scripts, but there is no reason you have to use scripts to do this. You can render the VML directly into your HTML and ship the rounded corners with the HTML. This allows the browser to render the rounded corners in the page flow as the page is parsed for a faster page loads and proper document flow. Today’s article will describe how to included rounded corners directly in your HTML for support in IE and all other browsers and is based on work originally done by Jonathan Snook[4].

How do it…

Enable VML on the body of your page (namespaced as v):

<body>
<xml:namespace implementation="#default#VML" ns="urn:schemas-microsoft-com:vml" prefix="v">
<!-- page body will go here -->
<xml:namespace>
</body>

Use the rounded rectangle VML tag to create a rounded rectangle:

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

Enable the VML via CSS for IE and other browsers:

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;
}

Unfortunately, this doesn’t work in IE 8 standards mode, so we have to degrade IE 8 to behave like IE 7:

<!--[if IE 8]>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<![endif]-->

How it works…

For starters we are using xml to pull in the VML[5] implementation, which this example wraps around the whole body, so that roundrect can be used anywhere on the page. However, you need only wrap parts of the page that contain roundrect elements. The rounded rectangle (roundrect) VML element has a number of properties, including the arcsize and fillcolor used here. The arcsize controls the size of the arc on the corners and is unfortunately relative to the box size. The fillcolor controls the background color of the element and cannot be controlled via CSS in IE <9.

This means that you need to duplicate the background-color defined in the CSS as the fillcolor attribute for older IEs. And you define border-radius in the CSS for modern browsers, but the arcsize attribute in VML for older IEs. This duplication is unfortunate, and it breaks the separation of design and layout rule, but is a necessary evil of this solution.

We have defined some CSS informing modern browsers to render the unknown v:roundrect element as as block element with rounded corners. The later part of the CSS declaration tells IE to use the default VML behavior for rendering (as defined by microsoft). Modern browsers will treat the v:roundrect element as other elements, so you can apply additional attributes like id, class, and data- for further control.

Out of the box, the VML solution works great in IE 6 and 7, but Microsoft changes the VML implementation in IE 8, so it breaks in standards mode. To work around this, we tell IE 8 to render as IE7 using the X-UA-Compatible meta tag. Most enterprise companies are already doing this, so they do not have to maintain different CSS for IE 7 and 8.

In summary, the pros of this solution is that you hve rounded corners in IE 6-8 that render with the page like other elements and need no special scripts for activating. The drawback is you need to duplicate some design in the markup and render IE 8 as IE 7. Overall, I would recommend gracefully degraded to non-rounded corners in older IEs, as this is not a perfect solution, but if you must support rounded corners, consider putting the VML directly into your markup, instead of relying on a script.


References

  1. CSS3 Pie
  2. Cross Browser Border Radius Rounded Corners (HTC access)
  3. jQuery Rounded Corners
  4. Rounded Corners Experiment IE
  5. VML Proposal

IE Issues with Name and Id Attributes

After building a site in FireFox that uses the "document.getElementById" to fetch a DIV, the engineer switches over to IE, only to find that the same call is returning a different element (most likely an A or INPUT element). After hours of debugging and frustration, said engineer gives up and instead starts writing a virus to uninstall IE from infected computers and replace it with FireFox (please do, I will donate!). Does that sound familiar; ...

IE6 Opacity Issue

Today, I experimented with the YUI Animation widget and experienced difficulty getting the opacity style to apply correctly in IE 6. It was fine in IE 7, FireFox, and Opera, but IE 6 ignored the opacity style changes. A quick web search revealed that in IE 6 opaque elements need a height and width, otherwise the opacity style will be ignored.

IE6 Opacity Filter Caveat

JavaScript Memory Leaks

On one of my projects, Mint.com, I recently noticed severe performance degradation in IE6 when the browser remains open. As it turns out a lot of the techniques used by various JavaScript Frameworks, and even my own JavaScript architecture, causes memory leaks. This is especially prominent in IE6, because its memory manager has poor heuristics for detecting JavaScript leaks. Its not as important in better browsers like, FireFox, but I do notice that Firefox ...