The corners can have any radius you care to have. This container has a corner radius of 32 pixels.

I've been experimenting with CSS methods lately, and I discovered there is still no really flexible way to create a container with round corners. Also, I have recently decided to move away from layout based on tables, which eliminates an earlier project of mine that created corner graphics for tables. Also, I wanted to avoid having to create a lot of little graphic files, one for each corner. So I set out to create a pure CSS solution, and here it is.

I want to emphasize that this method is pure CSS — it doesn't require any graphics or JavaScript. It relies on a Ruby generator script that you run during development for each required container style. The Ruby script creates a CSS stylesheet file containing the information required to create the container — the container's background color (or graphic image) and its corner radius.

Once you have generated the stylesheet file, simply make it available to the destination pages that need the corner effect, and then pop in some HTML structure for each container that is to have rounded corners.

That's the good news. The downside to this technique, not a very serious one, is that it requires a stack of special <span> tags, in the worst case equal in number to the corner radius * 2. For normal container radii, this isn't much of a burden. For example, the main container on this page has ten special <span> tags above, and ten below, the container content, in order to produce its 16 pixel radius corners.

The smaller blue container, on the other hand, has 48 <span> tags — 24 above and 24 below its content. So for large container radii, this method would be difficult to write by hand. But the Ruby generator script also creates a sample HTML page for each container design, and it is a simple matter of copying and pasting the required formatting blocks from the sample to the target Web page.

Details

It occurs to me that a prose description might not be the best way to convey the key ideas. So, here's a concise summary:

Purpose

Create Web page block elements with round corners, as on this page.

Requires

Just the ability to process CSS. No graphics, no JavaScript.

Method

Accomplished by varying the border width in a stack of <span> tags above and below the container's content area.

Different CSS stylesheet for each required container radius and color/background?

Yes.

HTML template for each container design?

Yes, this is created by the Ruby script. All one needs to do is copy & paste the template into each required container on the destination page.

Containers compliant with CSS?

Entirely.

Nested Containers?

Yes, to any degree.

Dynamic resizing?

Yes — try it on this page.

Typical Procedure

Here is how one would go about creating a round-corner container, step by step:

First, establish the desired container color (or background graphic) and radius. These should be known in advance because they need to be submitted to the Ruby script and are included in the generated CSS stylesheet. On the other hand, if the color changes later, it is a fairly simple matter to regenerate the stylesheet.

Create the container using the Ruby script. A typical entry:

$ create_round_corner_css.rb a0a0a0 ffffc0 11 yellow

This specifies a border color of "a0a0a0" (light gray) and a custom shade of yellow for the container background ("ffffc0"), a corner radius of 11 pixels, and a special label to be added to the generated file names ("yellow") to distinguish this design from others.

You may enter either color names like "white" or hexadecimal color designators. If you choose the latter, remember to enclose the colors in quotes, as shown above, so the shell doesn't interpret your entries as comments.

If you want to specify a graphic background instead of a color for your container, do it this way:

$ create_round_corner_css.rb a0a0a0 "url('path/filename')" 11 graphic

Remember, if relative addressing is used, the provided path must be correct for the destination page.

The color example would produce two files — a CSS stylesheet named "roundcorner_11_yellow.css" and a sample HTML page that shows the container named "roundcorner_11_yellow.html".

Move the CSS stylesheet into your working directory and add a reference to it in your page:

<link rel="stylesheet" type="text/css" href="roundcorner_11_yellow"/>

Move the required format block from the sample HTML file into the destination page. A typical format block looks like this:

The above sequence should typically be wrapped in a block-level container for page placement and margins. To avoid an appearance bug on some browsers, that block-level container should specify "display: block". Study the source for this page for some hints.

Make as many copies of the above block as required for this specific container style within the destination page.

Repeat the above procedure for each required round-corner container style, that is, for each combination of container color and radius.

Notice about this procedure that, once you have created some page content, you can fine-tune the colors for each container design without having to change any of the page content — but if you change a container's radius, you normally will have to replace the enclosing tag set (because the number of tags, and their class names, change with the radius).

Conclusion

The Ruby script is here. All one needs is a Ruby interpreter, available for most platforms. This script, as straightforward as it is, could easily be rewritten in Perl, by someone willing to make the effort.

Also, we can all look forward to newer versions of CSS, that are expected to include the ability to specify container corner radii without any hacks like this being necessary.

Revision History

10/06/2008 Version 1.4 — Added an optional border to the rounded-corner output (as on this page).

10/25/2006 Version 1.3 — Fixed a problem with MSIE by careful tuning of the generated values.

10/25/2006 Version 1.2 — Tuned the code to play better with background graphics.

10/25/2006 Version 1.1 — Reworked the generating code to allow background images as well as colors.