Rounded corners are a common element of web designs. Unfortunately, they have been frustratingly difficult to express in clean CSS / HTML. The long term solution is CSS3’s border-radius property, which is nicely supported in the current versions of Safari and Firefox. Sadly but unsurprisingly, this property is not supported in IE, even the upcoming IE8.
The new design for our website was full of rounded corners. As an avid Firefox user, I simply could not bear the idea of sending millions of little corner images when border-radius did the trick so well. Yet, IE7 is the dominant browser, so we couldn’t leave those users out in the cold.
I started looking for a technique that would meet these requirements:
- CSS3 border-radius aware browsers are sent clean, fast CSS with no corner images
- IE7+ gets a fallback using corner images
- The same HTML is used for all browsers - only the CSS is different
- Cosmetics in IE6 don’t matter - it’s OK to have square corners in this old browser
- No Javascript
Fortunately, I did find a flexible way to achieve this without too many problems. If you look at the BestInClass.com home page in Firefox, all of the corners and rounded buttons are implemented with pure CSS3.
The main drawbacks and restrictions are:
- It adds some non-semantic empty divs to the markup.
- It requires a way to deliver different CSS to IE.
- It cannot support rounded elements with a border that sit on top of unpredictable backgrounds.
Show Me, Don’t Tell Me
For those that want to skip over the why and get straight to the how, here’s a fairly minimal example in a single file.
CSS3 Rounded Corners With IE Fallback Example
The Code for Decent Browsers
The first thing to do is pick a unique style id for the rounded corners. This id will be used to find the right corner images for IE, so it needs to be unique considering the rounded block’s background color, border style, and background the block is sitting on top of.
First, the HTML. Wherever we want to have a rounded block, use the following elements:
<div class="rounded_STYLE rounded"> <div class="tl"></div><div class="tr"></div> ... contents of the block go here ... <div class="bl"></div><div class="br"></div> </div>
STYLE should be the unique style ID you chose. The empty tl and tr divs are the top left and right corners, while the bl and br are the bottom right. Those divs are not used at all in a CSS3-aware browser, but they are needed for IE’s image corners.
For a CSS3 aware browser like Safari and Firefox 3, this element can be styled very simply:
.rounded_STYLE
{
background-color: COLOR; /* if needed */
border: 1px solid BORDER_COLOR; /* if needed */
-webkit-border-radius: RADIUS; /* for Safari */
-moz-border-radius: RADIUS; /* for Firefox */
}
RADIUS would be something like 4px. And that’s it, you’re done in Firefox and Safari.
The Code for IE
Life would be good if we could stop there, but unfortunately the depressingly incomplete and non-standard IE remains the favorite of a majority of users… At least usage of IE6 has dwindled to the point where we no longer have to worry about pixel perfection there. And that opens the door for a decent solution in IE7 and above.
Did I mention that the HTML is the same? Yes I did. But we do need different CSS. Somehow, you need to hide the CSS for .rounded_STYLE above from IE, and feed it the following instead. On BestInClass.com we use dynamically generated CSS to do this, but you could use IE conditional comments as well.
.rounded_STYLE
{
background-color: COLOR; /* if needed */
border: 1px solid BORDER_COLOR; /* if needed */
position: relative;
}
.rounded_STYLE > .tl, .rounded_STYLE > .tr, .rounded_STYLE > .bl, .rounded_STYLE > .br
{
width: RADIUS;
height: RADIUS;
position: absolute;
}
.rounded_STYLE > .tl
{
background: url(/images/ui/rounded/STYLE-tl.png) top left no-repeat;
top: OFFSET;
left: OFFSET;
}
.rounded_STYLE > .tr
{
background: url(/images/ui/rounded/STYLE-tr.png) top right no-repeat;
top: OFFSET;
right: OFFSET;
}
.rounded_STYLE > .bl
{
background: url(/images/ui/rounded/STYLE-bl.png) bottom left no-repeat;
bottom: OFFSET;
left: OFFSET;
}
.rounded_STYLE > .br
{
background: url(/images/ui/rounded/STYLE-br.png) bottom right no-repeat;
bottom: OFFSET;
right: OFFSET;
}
Here RADIUS is again something like 4px and STYLE is the unique corner style id you chose. OFFSET should be set to -1px if you have a 1 pixel border for the element, or 0 if there is no border.
The CSS references four different corner images. In this example, they are located on the path /images/ui/rounded.
Making the Corner Images
You could generate these images using PhotoShop or another image editor. At least on a Mac, there is a much easier way for the non-PhotoShop savvy using the Preview application.
- Display your page in Firefox and take a screenshot of one of the corners.
- Open the screenshot in Preview. Zoom in so that you can see the pixels clearly.
- Select a square that is no bigger than RADIUS on a side and which is aligned with the straight borders of the element.
- Copy and New from Clipboard.
- Save this corner in your /images/ui/rounded directory using the name STYLE-CORNER.png where CORNER is tl, tr, bl, or br depending on whatever corner you chose.
- Use Flip Horizontal and Flip Vertical to generate the other three corners and repeat.
Congratulations, you should now have attractive anti-aliased rounded corners in all modern browsers, with Firefox and Safari users able to enjoy faster browsing without millions of teeny corner images clogging up the internets. Plus, you have the satisfaction of being future-compliant with CSS3 as it becomes increasingly available.
Created a site for a friend and hate the square corners, so have been looking for an easy rounded corner fix, but am not that familiar with this coding. Where in the index page does your html code go and where in the style sheet does the CSS3 coding go? Thanks–
@HD - I’ve added an example that should make it more clear.
[...] BestInClass.com Blog » Simple rounded corners with CSS3 box-radius and fallback for IE The long term solution is CSS3’s box-radius property, which is nicely supported in the current versions of Safari and Firefox. Sadly but unsurprisingly, this property is not supported in IE, even the upcoming IE8. (tags: tutorial corners webdev css css3) [...]
Thanks so much for your help! This fix is really great and works perfectly in Foxfire!! In IE7 though, while the top corners are now rounded, the bottom corners are still square. Scrolling down you can see that the rounded corners are way below the frame, at the very bottom of the page. Is there anything that can be done to fix that?
@HD - looking at your site, you have two declarations of the rounded_colhead div. The second one is beneath the footer and contains the bl and br divs. That’s why the bottom corners are going down there in IE. What you want to do is get rid of the second rounded_colhead div and move the bl and br divs to the end of the first rounded_colhead div (like in the example).
Initially, I had the code in the same place as the example, but I just ended up with a separate rectangle, with rounded corners, above my frame. I had to play around with it to get the corners to go where they were supposed to, and discovered that moving the bl and br code to the bottom was the only way it worked for me in Foxfire.
I could see a problem in IE7 with the actual corners that I had made, so I just created new ones. Foxfire is still fine and, in IE7, now the rounded corners that were floating at the bottom have disappeared, while the corners at the top are now stepped. Not sure why that happened but if it stays that way, I can live with it. (For some reason, it looks different on my computer than it does online, even though I have all of the same files here –the corners are still just squared in IE7.)
HD the browser is called FireFox ___not___ foxfire lol.. so please stop saying it
IMO using rounded corner image is better than using css (moz-border, etc). That is because rounded corners are rendered ugly: no anti-aliasing, at least in FF, corners does not look the same (in my case left corner is more rounded than right, even though i gave the same rounding value). Images are much more flexible, reliable, and cross-browser compatible.
The rounded corners are rendered nicely in the prevalent versions of Firefox and Safari. Firefox 2 had rather ugly jagged round corners, but that’s a pretty small percentage of users now. You can use the same image fallback technique to handle Firefox 2 users if you’re still concerned about them.
I haven’t seen a problem with different looking corners - what browser is that on?
[...] If by any chance you do want to start using the rounded function feature, but would like to have the same effect on other browsers that doesn’t support it, go here. [...]