Picnic Website Code Tutorials

The Ultimate Guide To Rounded Corners With CSS & Images Tutorial

I set out to find the best, most semantic, and most importantly, the easiest, method to round corners with CSS and images. Of course I found a wealth of information on the subject, varying largely from easy, to hard, to downright complicated. But like I said, I wanted something simple that I could easily wrap my brain around and incorporate flawlessly with each and every project. Well my fellow brainy-acts... I found, and built, just that! I narrowed it down to four ever so beautifully simple methods that I will layout for you and me below. Some are original ideas, and some are just optimized, cleaned up a little, and laid out in a way that even my grandma could follow.

Each method uses four images (except for method #4 which only uses one) and gives you the ability to freely change the dimensions of your div without having to go back to Photoshop to remake new, dimensionally correct images. You can make your rounded corner images in Photoshop, or you can make your images here like I did. Choose which ever method works better with your particular layout and/or the one you feel most comfortable with. Rest well assured that which ever method you choose to use is completely bullet proof and works flawlessly in all browsers. Trust me - I've spent hours upon hours testing them!

Method #1: The Rounded Holy Grail!

This method does not have the cleanest or least amount of code, but it is by far the easiest one to wrap your brain around. Also, and which happens to be a huge asset, it gives you the ability to specify a height on the rounded div (think min-height: 100%;). Coded as is, none of the other methods on this page have that ability. Of course, you can always add this functionality to them, now that your armed with this fix as specified below.

This method, that is a position relative box with four absolutely positioned corners, was abandoned long ago because of an IE6 rounding bug error that was never solved - until now that is! I solved it... I solved it! Can you here the tone in my voice? I'm very happy with myself. Although, "solved" is probably the wrong word - "hid" would be more appropriate. Either way, this long sought after technique is finally obtainable. Note however, that the "fix" is adding a pixel to the bottom & right side of each div (those are the only sides the bug affects). Therefore, if your layout is pixel perfect, and in IE6 only, those extra pixels will need to be accounted for.

The px-fix!

* html .br { /* fixed height/width px-fix */
	height: 100%; width: 100%;
	border-right: #888 solid 1px; /* same color as body */
	border-bottom: #888 solid 1px; /* same color as body */
	margin: 0 -1px -1px 0;
}
		

For a fixed height and width container the above fix works perfect. Unfortunatly though, it's not quite that simple - so sad :~(. If you have a % or inner content driven height and/or width then the above fix won't work. Fortunatly, there's a pretty easy solution as Paul O'B helped me figure out. So... for % or content driven height and/or width, instead use this fix directly below.

* html .br { /* non-fixed height/width px-fix */
	height: 9999px; width: 9999px; /* must be px - not em */
	border-right: #888 solid 1px; /* same color as body */
	border-bottom: #888 solid 1px; /* same color as body */
	margin:  0 -1px -1px 0;
}
* html #container { /* non-fixed height/width px-fix */
	overflow: hidden;
	display: inline-block; /* haslayout */
}
		

View Demo before px-fix added. View in IE6 to see bug
View Demo with px-fix added on fixed height/width container
View Demo with px-fix added %/content driven height/width container

The html

<div id="container">
	<span class="tl"></span><span class="tr"></span>
	<span class="bl"></span><span class="br"></span>
</div>
		

The CSS

* {
	margin: 0;
	padding: 0;
}
body {
	background: #888;
}
#container {
	width: 300px;
	height: 200px;
	margin: 50px auto;
	background: #CCC;
	position: relative;
}
.tl {
	background: url(images/tl.gif) top left no-repeat;
	position: absolute; top: 0; left: 0;
	height: 15px; width: 15px; /* height & width of image */
	font-size: 0; /* kills IE6 bug */
}
.tr {
	background: url(images/tr.gif) top right no-repeat;
	position: absolute; top: 0; right: 0;
	height: 15px; width: 15px; /* height & width of image */
	font-size: 0; /* kills IE6 bug */
}
.bl {
	background: url(images/bl.gif) bottom left no-repeat;
	position: absolute; bottom: 0; left: 0;
	height: 15px; width: 15px; /* height & width of image */
	font-size: 0; /* kills IE6 bug */
}
.br {
	background: url(images/br.gif) bottom right no-repeat;
	position: absolute; bottom: 0; right: 0;
	height: 15px; width: 15px; /* height & width of image */
	font-size: 0; /* kills IE6 bug */
}
		

Method #2: Simple & Sweet!

This one (Simple & Sweet), and the one above (Rounded Holly Grail) are my two favorite techniques. Each, in their own right, are just down right awesome! There's not much to say about this method - it's just easy! I'll let the code speak for itself.

View Demo

The html

<div id="container">
	<div class="top"><div></div></div>
	<h2>Some Text</h2>
	<div class="bottom"><div></div></div>
</div>
		

The CSS

* {
	margin: 0;
	padding: 0;
}
body {
	background: #888;
}
h2 {
	font-size: 1.2em;
	padding: 65px 0 80px;
	text-align: center;
}
#container { 
	width: 300px; 
	background: #CCC; 
	margin: 50px auto;
}
.top { 
	background: url(images/tr.gif) no-repeat top right; 
}
.top div { 
	background: url(images/tl.gif) no-repeat top left; 
	height: 15px; /* height of image */
	font-size: 0; /* kills IE6 bug */
}
.bottom { 
	background: url(images/br.gif) no-repeat bottom right; 
}
.bottom div { 
	background: url(images/bl.gif) no-repeat bottom left; 
	height: 15px; /* height of image */
	font-size: 0; /* kills IE6 bug */
}
		

Method #3: Hope Floats!

If you like working with floats then this method (Hope Floats) and method #4 (One Image Scrimmage) where built for you! Both are still very simple in comparison to other methods out there, but as always, a little extra care must be taken in order to clear the floats. But, you like floats, so you know that already!

View Demo

The html

<div id="container">
	<span class="tl"></span><span class="tr"></span>
	<h2>Some Text</h2>
	<span class="bl"></span><span class="br"></span>
</div>
		

The CSS

* {
	margin: 0;
	padding: 0;
}
body {
	background: #888;
}
h2 {
	font-size: 1.2em;
	padding: 65px 0 80px; 
	text-align: center;
	clear: both; /* clear top right/left floats */
}
#container {
	width: 300px;
	background: #CCC;
	margin: 50px auto;
	overflow: hidden; /* contain bottom right/left floats */
}
.tl {
	background: url(images/tl.gif) top left no-repeat;
	height: 15px; width: 15px; /* height & width of image */
	float: left;
	font-size: 0; /* kills IE6 bug */
}
.tr {
	background: url(images/tr.gif) top right no-repeat;
	height: 15px; width: 15px; /* height & width of image */
	float: right;
	font-size: 0; /* kills IE6 bug */
}
.bl {
	background: url(images/bl.gif) bottom left no-repeat;
	height: 15px; width: 15px; /* height & width of image */
	float: left;
	font-size: 0; /* kills IE6 bug */
}
.br {
	background: url(images/br.gif) bottom right no-repeat;
	height: 15px; width: 15px; /* height & width of image */
	float: right;
	font-size: 0; /* kills IE6 bug */
}
		

Method #4: One Image Scrimmage!

I believe Dave Woods first coined this one. Instead of the usual four images, Dave's method only uses one image - one perfect circle. It's quite an ingenious method, simple, and clean on the code - arguably the best of the bunch! You'll need a good photo editing program in order to make your circle. I used the Ellipse Tool in Photoshop CS3. If you don't have Photoshop, or any money, you can probably use Gimp (from what I hear it's almost just as good anyways) to create your circle.

View Demo

The html

<div id="container"> 
	<span class="tl"></span><span class="tr"></span>
	<h2>Some Text</h2>
	<span class="bl"></span><span class="br"></span> 
</div>
		

The CSS

* {
	margin: 0;
	padding: 0;
}
body {
	background: #888;
}
h2 {
	padding: 65px 0 75px;
	font-size: 1.2em;
	text-align: center;
	clear: both; /* clear top right/left floats */
}
#container {
	width: 300px;
	background: #CCC;
	margin: 50px auto;
	overflow: hidden; /* contain bottom right/left floats */
}
.tl {
	background-image: url(images/circle.gif);
	height: 15px; width: 15px; /* height & width of image */
	float: left;
	font-size: 0; /* kills IE6 bug */
}
.tr {
	background-image: url(images/circle.gif);
	background-position: 15px 0px;
	height: 15px; width: 15px; /* height & width of image */
	float: right;
	font-size: 0; /* kills IE6 bug */
}
.bl {
	background-image: url(images/circle.gif);
	background-position: 0px 15px;
	height: 15px; width: 15px; /* height & width of image */
	float: left;
	font-size: 0; /* kills IE6 bug */
}
.br {
	background-image: url(images/circle.gif);
	background-position: 15px 15px;
	height: 15px; width: 15px; /* height & width of image */
	float: right;
	font-size: 0; /* kills IE6 bug */
}
		

A little Explanation: font-size: 0; corrects a problem with IE6 whereby it won’t render smaller in height than the base font size so this fixes that little bug. The px-fix for method #1 (non-fixed height/width) is 9999px rather than 999em, because 999em of font-size: 0; is 0. Therefore, in order for the borders to be tall and wide enough to hide the other IE6 bug they need to have a px value. Anywhere you see a "haslyout" comment, it's yet again, for IE6. If there is no width or height declared on the container a haslayout fix is usualy in order. If your wondering why IE7 doesn't seem to need a haslyout fix in any of the examples, it's because overflow: hidden; gives IE7 layout.

Sponsors

Top Donators

Friends of Mine