I started this exercise with a simple bordered div which contained four divs that each had a background-image and that were positioned in each of the corners. This worked great in Mozilla 1 and Netscape 6, but not anywhere else. As I fixed bugs in each of the other browsers implementations, I ended up with this code.
If you can find something simpler (that works in every browser and in every situation), please let me know.
Editor’s Note
When I wrote this article in 2002, it was one of the few methods for making rounded corners. CSS support in web browsers has improved dramatically since then and I no longer use this technique. Instead I use background-image
s and wrapper div
s as needed.
Second edit: And now there’s CSS 3’s border-radius properties!
the examples
The examples includes relative positioning, absolute positioning, fixed positioning, and static positioning, as well as floated and centered divs. Any “bullet-proof” cornering method needs to work in all of these situations. If you have one method for one situation and another for different situation, it’s kind of a pain.
where it works:
div positioning | ||||||||
---|---|---|---|---|---|---|---|---|
static | centered | float left | float right | float w/ negative margin | fixed | absolute | relative | |
IE5/win | Y | Y | Y | Y | Y | Y | Y | Y |
IE5.5/win | Y | Y | Y | Y | Y | Y | Y | Y |
IE6/win | Y | Y | Y | Y | Y | Y | Y | Y |
IE5/mac | Y | Y | Y | Y | Y | Y | Y | N [1] |
Moz1 | Y | Y | Y | Y | Y | Y | Y | Y |
Net6 | Y | Y | Y | Y | Y | Y | Y | Y |
Net7 | Y | Y | Y | Y | Y | Y | Y | Y |
Op4/win | Y | Y | Y | Y | Y | Y | Y | Y |
Op5/win | Y | Y | Y | Y | Y | Y | Y | Y |
Op6/win | Y | Y | Y | Y | Y | Y | Y | Y |
Op7/win | Y | Y | Y | Y | Y | Y | Y | Y |
Op5/mac | Y | Y | Y | Y | Y | Y | Y | Y |
Safari/mac | Y | Y | Y | Y | Y | Y | Y | Y |
Konq 3 | Y | Y | Y | Y | Y | Y | Y | Y |
- IE5/mac doesn’t play well with the contents of relatively positioned divs, in general.
the XHTML:
<div class="contentWrapper">
<div class="content">
<img class="borderTL" src="/images/borderTL.gif" alt="" width="14" height="14" />
<img class="borderTR" src="/images/borderTR.gif" alt="" width="14" height="14" />
<h1>Here be content!</h1>
<!-- IE5/win puts the margin-bottom of the content div's final element
OUTSIDE the containing box (div.content), instead of putting it inside
the containing box's edge. So it needs this spacer. -->
<div class="roundedCornerSpacer"> </div>
</div><!-- end of div.content -->
<div class="bottomCorners">
<img class="borderBL" src="/images/borderBL.gif" alt="" width="14" height="14" />
<img class="borderBR" src="/images/borderBR.gif" alt="" width="14" height="14" />
</div>
</div><!-- end of div.contentWrapper -->
the CSS:
.roundedCornerSpacer {
margin: 0px; padding: 0px; border: 0px;
clear: both;
font-size: 1px; line-height: 1px;
}
/* In the CSS below, the numbers used are the following:
1px: the width of the border
3px: a fudge factor needed for IE5/win (see below)
4px: the width of the border (1px) plus the 3px IE5/win fudge factor
14px: the width or height of the border image
*/
.borderTL, .borderTR, .borderBL, .borderBR {
width: 14px; height: 14px;
padding: 0px; border: 0px;
z-index: 99;
}
.borderTL, .borderBL { float: left; clear: both; }
.borderTR, .borderBR { float: right; clear: right; }
.borderTL { margin: -1px 0px 0px -1px; }
.borderTR { margin: -1px -1px 0px 0px; }
.borderBL { margin: -14px 0px 0px 0px; }
.borderBR { margin: -14px 0px 0px 0px; }
/* IE5-5.5/win needs the border scooted to the left or right by an
additional 3px! Why? */
.borderTL {
margin-left: -4px;
ma\rgin-left: -1px;
}
html>body .borderTL {
margin-left: -1px;
}
.borderTR {
margin-right: -4px;
ma\rgin-right: -1px;
}
html>body .borderTR {
margin-right: -1px;
}
.borderBL {
margin-left: -3px;
ma\rgin-left: 0px;
}
html>body .borderBL {
margin-left: 0px;
}
.borderBR {
margin-right: -3px;
ma\rgin-right: 0px;
}
html>body .borderBR {
margin-right: 0px;
}
/* To get around a known bug in IE5/win, apply the
border (no margin, padding or positioning) to the
content class and apply whatever positioning you
want to the contentWrapper class. */
.content {
margin: 0px;
padding: 0px;
border: 1px solid #000000;
}
.contentWrapper {
/* position this div however you want, but
keep its padding and border at zero */
padding: 0px;
border: 0px;
}
Comments6
"bottomCorners" class
John thanks for the great code. One thing through, you call a class named "bottomCorners". I have gone through every line in the CSS and can not find it anywhere. Could you help? Thanks.
Just a container
The
<div class="bottomCorners">
is just a container for the bottom images. It doesn’t need any CSS.Originally, I had some CSS for it, but in the course of developing the code, the "bottomCorners" class lost its function. Like an appendix, you can safely remove it.
Sorry for the confusion.
In case you haven't seen this
In case you haven't seen this yet - your Web site is listed below as #9 of Livingston's Top Picks.
"E-Business Secrets" from InfoWorld.com, April 2, 2003
Where are the images?
Hi John,
I don't mean to be dense, but where can one see/download the images pertaining to rounded corners referenced in your example, i.e. src="/images/borderBL.gif", etc?
Using your own images
You can see the images in the html on the examples page. I’ve been meaning to make a Photoshop file available to ease creation of your own corners, but it’s still on my to-do list.
All of my corner images are 14px by 14px and overlay a 1px border. So make sure that when you create your own images and possible change the thickness of the border, you also change the corresponding dimensions in the CSS.
DOCTYPE!
Thank you so much for your effort on the rounded corners!
I spent a few hours (!) figuring out that the DOCTYPE is incredibly important.... I just couldn't get your example to work until I discovered, that it was because my editor put in a DOCTYPE like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
and your site used a
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
But this DOCTYPE will work too:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
It made all the difference. Now I know. Hopefully, this will save the next guy the same trouble...
Thanks for your effort. It is very much appreciated! (I'm using it on http://morch.com - a work in progress :-)