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 8 Compatibility Issue with YUI 2 Selector Component

I realized recently, in my work on Mint.com, that the YAHOO.util.Selector.query function does not work properly in IE 8 compatibility mode when performing a search against the class and for attributes. The issue is that previous versions of IE defined these attributes names as className and htmlFor, while IE 8 changed them to follow the standard. And a faulty if statement in the selector component does not properly use the legacy names when developers ...

IE Issues to Avoid

As many of you know, Mint.com has just come out of beta with our new release (v8). During this last development cycle we revamped our transaction page to have an inline edit, instead of using div-based popup dialogs. This has been my baby for the past two months, and was a lot of work. During the design and development process most browsers behaved very well, but IE really gave me some problems. Today, I ...

The New IE PNG Fix

I have been using the iepngfix.htc tool for years, allowing me to correct IE6s lack of support for alpha transparencies in PNGs. The tool is called via a CSS behavior, which loads the HTC file containing JavaScript that searches the CSS for PNG backgrounds and automatically applies the IE6 transparency filter. So once the page loads, the PNG background images are corrected. There is a slight flicker as the correct happens, but it is ...

Two Helpful IE Hacks

For a change of pace, below is a short article about CSS.

* (star) or Holly Hack

In most browsers the CSS root tag is html, so you might write:
html body { font-size: 12px; }
In, IE (version 6 and lower) Holly (Bergevin, i think), found that the DOM actually starts with *, so you might write:
* html body { font-size: 12px; }
Because only IE 6 and lower understands the ...