Easy, Liquid, Round-Cornered Boxes
Using Simple HTML and CSS

by Frances Cherman

It seems as though round-cornered boxes should be a simple task for CSS, yet the sheer variety and complexity of approaches available on the Web attests otherwise. It's certainly easy enough to use an image of a round-cornered box as the non-repeating background of the element holding your content, or a div surrounding that element, but this approach has two problems:

This liquid, round-cornered box requires far less markup than most. The top two corner images go into a single div above the content element; the bottom two into a div below. There are no complicated div nestings or sequences, and no cryptic formulas for the margins and padding. You can set the display and float properties for all four images with a single rule, then use a second rule with sibling selectors (img+img) to float both right corners off to their places. Go ahead and bump up the text size or resize your browser window: the box is completely liquid in both directions.

In this example (class="borderbox"), I've created the effect of a round-cornered border by assigning the content paragraph a border whose width and color match the radius and color of the corner images. If you want to use a narrower border, specify a smaller radius for the images (these are 15px). If you don't want the text to be liquid, assign a width to the outer container. Since this method doesn't require elements to be positioned "just so", you're free to play with the padding, borders, and margins without fear of breaking the box.

Here's a fun effect (class="specialeffectbox") created by making the border color different from the color of the corner images. If you're in a hurry, graphically impaired, or lazy, you don't even have to create your own corner images: Cornershop will do it for you in seconds.

Fixed-size images vs. flexible-size containers

The first problem is that an image is a fixed size, and your text container may not be: you may want the flexibility to lengthen or shorten the text without resizing the background image; the user may resize the text, causing it to overflow the box; or, you may want to keep your layout liquid so that elements resize to fit the user's viewport. The most common solution is to place the content in a flexible-size container, set the background color, and create matching-color images of just the corners. But this leads to the second problem: how to get the images to go where you need them.

Go to your corners.

Using the "position" property to place your images doesn't work because images are inline elements. Several solutions nest the content within multiple, otherwise empty divs, assigning each corner to its own div and using the background-position property to place the images in their respective corners. One method involves four overlapping, offset boxes and an arcane formula for margins and padding that recalls the trauma of Algebra IV. Another calls for no images at all (very attractive to the Photoshop-impaired) but gobs of empty divs of gradually decreasing widths. Almost every approach I found relies on code that's so unintuitive and acrobatic it hurt my head just to think about it.

Towards a simpler approach.

I found hope in Adam Kalsey's technique. He places the two left corners in the HTML and the two right ones in the CSS as backgrounds, using the "background-image-position" property to move them to the right. His method uses less code than most, and I like the intuitiveness of placing the images before and after the content in their own divs, but I was bothered by having to treat the left and right sets of images in entirely different ways. Logic says that if the images are going to function the same way visually, they should all be treated the same way "codically" (if that isn't a real word, it should be).

I wanted all four images in the HTML—each on the same ‘level’ as its visual sibling—yet, how would they get to their ‘corners’? The solution that came to me is so simple, I keep thinking I must have overlooked something fundamental; if so, I'm sure I'll hear about it. Meanwhile, this method appears to work—at least in Firefox and Safari*—is easily adaptable without advanced math, and it validates. I simply applied the CSS ‘display:block’ property to the images to change them from inline to block-level elements, and then used ‘float:left‘ and ‘float:right’ to send them their proper corners. Here are the four corner images I used for all three demos; you may prefer a smaller or larger radius:

The code is thoroughly commented. Happy rounding!

* Note: This demo has not been tested on any version of IE. Volunteers welcome.