Variable Width and Height XHTML/CSS Rounded Corner Boxes

By Chris Maxwell  1/17/07

Have you ever needed to create containing boxes (aka "brickets") with rounded corners that varied in size and maybe even style throughout the site?

I developed a method that I think is useful enough to share, and although it is not Earth shattering by any stretch of the imagination, the good thing about it is that it will allow you to change the width and height for individual boxes or groups of boxes via CSS or the content (liquid). You can also easily change the images you use, and one added bonus is that no part of the top or bottom portions of the box are lost because of containing div's that hold images.

The technique I use is based on the AListApart's "Sliding Doors of CSS". The following article describes how to correctly slice the rounded corner elements from an image using Photoshop, and then how to build the XHTML and CSS that renders them. Creating the initial image is something your going to have to figure out on your own though - that is too design focused for this article.

I hope this article is helpful and by no means is it the end all method. It is just the way I do it. Here are some other methods out there that may be more useful to you, and probably even better than my method:

Preparing the images

Step 1

First, in Photoshop, open the "box.gif" you wish to code and remove any excess background if there is any (anything beyond the outer borders of the box).

Image -> Trim... -> select Transparent Pixels

Step 2

Save the file as a GIF.

File -" Save for Web...

Step 3

Open the GIF in Photoshop and cut out three sections: 1- a slice of the top portion of the bricket, 2- a slice of the middle, and 3- a slice of the bottom portion of the box. Each slice should be approximately 10px in height and the entire with of the image.

I like to use the Rectangular Markee tool to slice. Once I have selected an area I use Ctrl - c to copy the section, Ctrl - n to open a new window to paste the section into, and Ctrl - v to paste it.

What you should be left with are three windows, each with a slice of the original image.

Step 4

The next step is to split the image in each window into two sections of the bricket; the left side and the right side of the bricket (remember we are using the Sliding Doors technique to allow the bricket to expand and contract horizontally).

To begin your splicing choose one of your sections, lets say the top section. If the image width is 287px, as is the case with my image, and you are creating the right side of your sliding bricket then you need to slice off the left side of the bricket - the left rounded corner.

Use your canvas tool to remove the left side. For this example I will clip off 87px from the left of the bricket so that the remaining image will be an even 200px.

Image -" Canvas size... -" change width to 200px -" select middle right box -" ok -" proceed

What you are left with is the right side of the bricket. Save the slice as a GIF called "tr" for "Top Right" ("tl" for "Top Left", "ml" for "Middle Left", etc).

To create the right side of the bricket, undo the changes you just made to the section.

Edit -> Step Backward

Then repeat the last steps except this time select the middle left box and save the result as "tl" for "Top Left".

Now you have your left side of the bricket.

It's hard to see in the image above, but here are what the ends of the new slice look like:

Left Side:          Right Side:

Step 5

You just created two images from the top section. Now you need to do the exact same thing for the middle section and the bottom section. When you are done you will have 6 images: tr.gif, tl.gif, mr.gif, ml.gif, br.gif, bl.gif.

Step 6

If you applied the XHTML framework and CSS your bricket would look like this:

Not bad, but there is one problem... notice the slight lines on the corners of the bricket? Because we used a transparent image, the rounded corners of the images naturally are transparent which would be fine if our brickets were not liquid, but since we are using the Sliding Doors technique to achieve vertical liquidity, any image below the top image will show through. The line you see is the border of the opposite sides image.

To remove this you will need to fill in the transparent areas of your images with the color of what ever back ground you are matching. For me that would be white. To fill in the transparent areas I use the Pencil Tool.

From    to

Building the XHTML framework

Now that you have completed the image prep portion of this tutorial, the next part is easy. The frame is nothing but a series of embedded DIV's. Each DIV will hold an image element which will be applied through CSS - where the real magic takes place. Here is your basic framework:

	<div class="box">
		<div class="mr">
			<div class="ml">
				<div class="tr">
					<div class="tl">

						<h2>TITLE</h2>

					</div> <!-- eof tl -->
				</div> <!-- eof tr -->
				<div class="br">
					<div class="bl">

						<p>CONTENT</p><

				  </div> <!-- eof bl -->
				</div> <!-- eof br -->
			</div> <!-- eof ml -->
		</div> <!-- eof mr -->
	</div> <!-- eof box -->

From the class names you can probably guess which images will be called from each DIV.

Applying CSS

Here is where all the matching begins. Each slice you created previously is called via the XHTML div structure and the following CSS:

	.box { /* you can specify a width here, or allow it to default to 100% of its containing box */
		margin-bottom: 10px;
		}

	.box h2 {
		float: left; /* this allows you to float content to the right */
		width: 200px; /* the width is variable and depends on the title content */
		padding-top: 10px;
		padding-left: 12px;
		}

	/* top border */

	.tr {
		height: 40px; /* i have set the height to 40px to allow for header content */
		background: url(images/bricket1/tr.gif) top right no-repeat;
		}

	.tl { /* title div */
		clear: both;
		float: left;
		width: 100%; /* required */
		height: 40px; /* this is variable but must match .tl height */
		background: url(images/bricket1/tl.gif) top left no-repeat;
		}

	/* mid border */

	.mr {
		background: url(images/bricket1/mr.gif) right repeat-y;
		}

	.ml {
		background: url(images/bricket1/ml.gif) left repeat-y;
		}

	/* bottom border */

	.br {
		background: url(images/bricket1/br.gif) bottom right no-repeat;
		}

	.bl { /* content div */
		height: 100px; /* here is where you set your heights, I am arbitrarily setting it to 100px */
		padding-top: 10px;
		text-align: center;
		background: url(images/bricket1/bl.gif) bottom left no-repeat;
		}

Variations

When I need to make variations on images used, widths, and/or heights I just add a class to the .box DIV that I want to change like this:

	<div class="box variation">

Then I use the new class .variation in the CSS:

	/* top border */
	.variation .tr { /* changes */ }
	.variation .tl { /* changes */ }

	/* mid border */
	.variation .mr { /* changes */ }
	.variation .ml { /* changes */ }

	/* bottom border */
	.variation .br { /* changes */ }
	.variation .bl { /* changes */ }

And there you have it!

Not to painful I hope. If you want to see this code in action take a look at these samples.