“Bullet-Proof” Rounded Corners

By John, 10 August, 2002

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-images and wrapper divs 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:

browsers that support rounded corners
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
  1. 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;
}

Topics: CSS

Comments6

The content of this field is kept private and will not be shown publicly.

Kwame Hubbard (not verified)

21 years 9 months ago

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.

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.

Audrey L Berns (not verified)

21 years 2 months ago

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?

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.

Peter Mørch (not verified)

21 years 1 month ago

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 :-)