Theres no shortage of techniques for achieving cross-browser rounded corners. Most of the techniques involve taking an otherwise simple box and adding markup and CSS until all browsers (IE 6+, Firefox, Safari, Chrome) agree to round the corners. Of course the great hope today is to use CSS3 techniques such as border-radius
or multiple backgrounds and of course those approaches won't work in Internet Explorer 8 or below. Ironically, one of the best places to find some of the old school CSS solutions is on the MSDN page describing border-radius
. For modern browsers, the border-radius
property will do a good job of rounding corners. To support all browsers some clever techniques will need to be used.
For the uninitiated
Goals
To successfully approximate border-radius
, the content of the box should appear as it does in a regular box with a border applied.
- Start with a simple box
- The box's content should appear similarly with or without
border-radius
support - The solution should work in all browsers (IE6 is a bonus) with or without
border-radius
support - The solution should scale with the content and obey the box
- with fluid height/width
- with fixed height/static width
- Bonus Points: easy to implement
A Simple Box
As mentioned above, border-radius
is supported in roughly 50% of browsers globally (as of February, 2011). The other 50% of browsers are IE 8 and below.
|
Above is the simple box that we want to give rounded corners. The goal is to have it look something like the picture below.
|
Again, in all browsers (except IE 8 and below) the above CSS will add rounded corners to any .box
. According to the Mozilla border-radius
documentation the -moz-
and -webkit-
prefixes are for older versions of Firefox and Safari respectively. IE 9, Firefox 4, Safari 5 and Chrome 4+ all support the standard W3C border-radius
property without the vendor prefix.
Polyfills
With the above goals in mind a straight-forward solution might be to force IE 8 and below into line using some creative JavaScript-based technique that won't require any images to be created.
CSS3 PIE
CSS3 PIE an extremely clever polyfill technique that reads and processes the CSS file using a DHTML behavior in Internet Explorer to find the border-radius
rules and then generates a VML object, placing it behind the target element. A tool like CSS3 PIE can be used to support rounded corners in IE 8 and below. The big drawback to CSS3 PIE is that it works best on static content and is slow to render. Because the VML object is placed behind the box, it must remove all of the visible styles from the box including border and background images. Those visible styles are then applied to the VML object.
View the page above in IE 8 or below and the corners should look correct. Refresh (hit F5) repeatedly and see that the corners do not appear instantly. Inspect the HTML in IE 8 or below (hit F12) and see the VML object. It's worth noting that CSS3 PIE isn't particularly slower than any other similar polyfill.
Pros:
- Easy to implement
- Targets IE8 and below only
- Closely approximates native CSS3 rounded corners
Cons:
- Slow:
- It's using JavaScript in Internet Explorer 8 and below and JavaScript is slow in those browsers.
- Performance gets worse for each element where rounded corners are applied.
- Fragile:
- If the element visibility is toggled with JavaScript, CSS3 PIE will have issues.
- CSS3 PIE can cause other unexpected display issues, such as visual discrepancies when zooming in IE7.
jQuery Corner
There are also tools like jQuery Corner and Curvy Corners that will use native border-radius
in supported browsers and use a series of 1px tall div
elements to polyfill in other browsers. This is a popular solution to the problem that works by adding in extra div
elements. Each div
is given a right and left border the same color as the page behind the element and the border widths are altered to create appearance of a rounded corner.
Pros:
- Easy to implement
- Falls back to native CSS3 for rounded corners in supported browsers
Cons:
- Support for borders doesn't work well in IE (oops!)
- The corners cover the content within the box (this could be fixed)
- No anti-aliasing in Internet Explorer. Each pixel of the rounding is a solid color due to the way the rounding effect is achieved
- Over a dozen other virtually useless corner templates included in the package
Background Images
If native border-radius
isn't an option (and polyfills aren't stable enough), then it will take several images to do the trick. In some cases a sprite can be used. For the examples below we'll try to create the same 1px red border with a 12px border-radius
from above. Rounded corner images can easily be created at a number of on-line generators. My favorite is the Rounded Corner Image Generator.
- corner-tl.png — top left corner
- corner-t.png — top border
- corner-tr.png — top right corner
- corner-r.png — right border
- corner-br.png — bottom right corner
- corner-b.png — bottom border
- corner-bl.png — bottom left corner
- corner-l.png — left border
- corners.png — a rounded corner sprite. All of the corners and borders are combined into one image.
As is evident by the top, bottom, left and right images, when the border is a simple 1px solid color, those images may not be necessary and could be replaced by actual borders. For these examples images were used anyway because it's more common that the borders are complex and need to be images — particularly when shadows are involved.
Onion Skinning And Sliding Doors
Most rounded corner techniques are a variation on the classic Onion Skinned Drop Shadow article or the Sliding Doors article (part 2). For instance, one of the techniques from the MSDN article uses a variant of the sliding doors technique. These techniques are effective but they're not particularly easy to implement. They're also limited because they try to accommodate IE6 which has a fair share of documented CSS issues. There is no shortage of cross browser rounded corner articles. The majority mention either using a method similar to CSS3 PIE or jQuery Corner above or they recommend using an image + HTML + CSS solution like the ones below.
- Typing out multiple nesting
div
tags can be tedious and difficult to replicate across many pages on a large site. - The most bullet-proof solutions would require as many as 8 wrapping
div
s (top, bottom, left, right, top-left, top-right, bottom-right, bottom-top) to properly imitate the capabilities ofborder-radius
. - Specifying complicated HTML and CSS layouts limits the situations in which it can be used.
Using Onion Skinning
Onion skinning is the process of adding multiple wrapping div
elements to a .box
element and then applying a different background image to each of the layers. This technique was originally developed for creating drop shadows but can easily be adapted to creating rounded corners.
Pros:
- Very flexible and simple CSS
- Can easily be scaled back to not require the top, bottom, left and right
div
elements - Easy to understand HTML
- Content is naturally on top of the background images, no need to use relative positioning to avoid content clipping
- Works in all browsers, including IE6
Cons:
- The
.content
needs to have a height set if it is applied to a fixed-height box - The corner images cannot be transparent because they need to cover the edges of the box
- Very ugly markup
- Cannot use a CSS sprite for corners or sides because of how CSS backgrounds are specified
|
The HTML markup above shows how onion skinning would work on the original simple box from the beginning of the article. Each layer of the onion contains the background image for one of the sides or corners. It's possible to re-use the .box
and .content
elements which results in only 7 extra wrapping div
elements. The sides are wrapped first so that the corners can cover them up later.
|
The accompanying onion skinned CSS is very straightforward. Each layer gets its own background image and it is positioned appropriately. The sides repeat and the corners do not.
- For fixed-height boxes, the
.box
height (200px in this case) should be duplicated on the.content
- To replicate the look of a box with a border, padding should be used to space content away from the edges (for a 4px border, user 4px padding, etc.)
- To account for how collapsing margins would interact with a real border,
padding-top
andpadding-bottom
need to be set on the.content
Using Sliding Doors
The sliding doors technique uses a content area sandwiched between a top and a bottom element. The top and a bottom each contain elements for left and right corners. This technique allows for great flexibility with using image sprites and allows the corners to be fully alpha transparent if desired. The markup appears to be much more sensible but the CSS is much more complicated.
Pros:
- Allows for image sprites and alpha transparent corners
- Sensible HTML markup
- Works in all browsers, including IE6
Cons:
- More complex CSS
- For fixed height boxes, extra calculations are required to account for padding on the top and bottom of the box
|
In the sliding doors example, a few extra div
elements are added to the top and bottom of the box and the content is wrapped in some left and right div
elements. This allows the left and right backgrounds to grow with the height of the content. In a case where the left and right border is a simple solid color these wrappers may be eliminated and the border applied directly to the .content
.
|
To correctly position all of the pieces, the box is given a top and bottom padding the same height as the corner (12px in this case). For a fixed height box this padding should be subtracted from the original box height. Then the .top
and .bottom
containers are given a top and bottom margin of -12px respectively (the same as the top and bottom padding on the box). The .top
and .bottom
containers are also given left and right margins the same as the width of the corners (again, 12px in this case). The corners are then absolutely positioned into the empty space created by giving them a -12px left and right position respectively.
The .left
and .right
wrappers wrap the .content
and operate more like the onion skinning techniques. The right div
is given a 1px top and bottom padding to account for collapsing margins and the .content
is given a negative margin to pull its edges to the edge of the box. Adding position relative and a z-index ensures that the .content
is above the top and bottom div
containers to avoid content clipping.
The left and right wrappers are particularly challenging because of the need to apply a 100% height to ensure they are the correct height in conjunction with the 1px top and bottom border applied to prevent collapsing margins from affecting the layout. This isn't an issue in IE 6 and 7 because they collapse the top margin even when there's a border. But for the other browsers the 1px border combined with a 100% height on the .right
wrapper makes it 2px too tall. By using an alternate method for spacing in IE 6 and IE 7, the padding can be negated by adjusting the box-sizing
.
Using Absolute Positioning
A solution that is not often posited is using absolute positioning to place all of the corners and sides on the box. This solution takes advantage of how most browsers (except IE 6) handle conflicting right
and left
properties on an element. For instance, a rule like .top {position: absolute; left: 12px; right: 12px;}
effectively stretches .top
across the full width of its nearest positioned parent. IE 6 ignores the conflicting rules which makes it more difficult to support that browser with this technique.
Pros:
- Very simple CSS
- Very simple HTML
- Supports fluid and fixed height/width boxes automatically
- Supports dynamic content
Cons:
- Doesn't work in IE 6
|
In the example above, the 8 corner and side spans are added to the top of the .box
and the content of the box is wrapped in a .content
div
. The .content
is to allow for proper layering so that the corners are below the content.
|
The CSS for absolute positioning is really straight-forward. The sides and corners are all set to be position: absolute
and given z-index: 1
while the .box
and .content
are set to position: relative
and the .content
is given z-index: 2
. The corner span
s are positioned in the appropriate corner and the sides are positioned on the appropriate side. The key trick is giving, for instance, the .top
a left: 12px
and a right: 12px
. The apparently conflicting riles actually stretch the span
the full width of the .box
. The same is done with the .left
and .right
sides, giving them both top
and bottom
properties to stretch them the full height of the .box
. The 12px is to allow space for the corners to avoid overlap.
Ignoring Legacy Browsers
Using Border Radius
As mentioned at the start of this article, border-radius
can be used to add rounded corners to a .box
.
Using Multiple Backgrounds
It's now possible to use multiple backgrounds in newer browsers including Firefox 3.6+, IE 9, Safari and Chrome. Multiple backgrounds are layered in in the order they are added in the CSS with the first image being the top-most layer. Using this technique for corners might seem slightly silly given the existence of border-radius
in every browser that supports multiple backgrounds, however there are times when the native border-radius
cannot accomplish the same thing as images.
Pros:
- No extra markup required
- Easy to understand CSS
- Can be used to create custom graphic borders that
border-radius
cannot support - Can be combined with mark-up based solutions and simple JavaScript to support legacy browsers
Cons:
- Won't work in IE 8 or below
- Won't work in Firefox 3.5 or below
- Cannot be used with sprites (but inline images would work)
|
Conclusion
While CSS3 PIE is promising, it is still difficult to use on large scale sites. The JavaScript-based polyfill techniques don't seem to work very well in IE 8 and below at the moment (this is extremely unfortunate). Most of the techniques for applying backgrounds require ugly markup or intensely difficult CSS to accomplish. I personally prefer the Absolute Positioning technique as it is the easiest to implement and offers some support of Legacy browsers. The fact that IE 6 is not supported is not a huge issue given that IE 6 is no longer necessary to support for most projects (4.6% globally, 2% in the US and Europe as of February 2011).
In the future I intend to create a simple jQuery plug-in that will apply the absolute positioning technique to a .box
.
border-radius
— Supported in only 50% of browsers as of February 2011- Multiple Backgrounds — Supported in only 46% of browsers as of February 2011
- CSS3 PIE - Interesting technique with limitations on large scale sites.
- jQuery Corners - Doesn't work as intended. Could probably be fixed but no one has.
- Onion Skinning - Ugly HTML, easy CSS, works in 100% of browsers
- Sliding Doors - Cleaner HTML, uglier CSS, works in 100% of browsers
- Absolute Positioning - Clean HTML, easy CSS, doesn't work in IE6