I'm sure this has been done a million times before, but it just came to me yesterday, so I figured I'd write up an example on my site. Also note that I'm not suggesting these boxes actually look cool, it's the CSS technique, that while very simple and maybe obvious, is actually cool.

And don't forget to post comments or feedback, thanks!

This box is lame!

In order to be resizable vertically, the background image has been split into two separate files, bg_top.gif and bg_bottom.gif.

The outer div background is the overly-tall top image, anchored to the top, while the inner div background is the short bottom "end cap" image, anchored to the bottom.

While this is a pretty standard way to make a resizable box, it requires two images (two HTTP requests), which isn't great!

Also, keep in mind that this implementation is limited to the height of the top image. If you want an infinitely-resizable box, you'd actually need three images (three HTTP requests), which is not at all good!

This box is cool!

While the CSS used for this box might be slightly more complicated, the benefit is that only one image, bg.gif, is used. And when you inspect that image, you'll see that it actually contains the background for not one, but two differently styled boxes!

In fact, you can use this single image for many other CSS sprite images, thereby further reducing the number of HTTP requests your page makes, which helps to save page load time.

Are there any caveats? Not really. You're going to be height-limited, so if you really want an infinitely-resizable box, you're going to need three images. But that shouldn't be necessary, since you can just make your single image as tall as you need, and then some. For example, these box images are 1000px tall, which should be more than enough for the content.

This box is also cool!

(continued) Also, when you calculate the box width, you need to take padding into consideration. Just a little math, which shouldn't be a problem. Finally, if you care about how the box renders in IE6, you'll need to hack in a few styles (shown below, prefixed with _ so they only affect IE6).

If you want to use this technique, you should only need to change the box and shim background image, the box width and padding, and if you set the shim height to the value of the padding (or less), you won't need to mess with z-indexes. Also, for IE6, you'll need to set the padding appropriately.

Also, if you want to set the height to something specific, you'll need to set it on the parent container (in the "lame" version, you'd need to set it on the inner container).

The code

/* Two HTTP requests? How lame is that? */

.lame_box {
  width: 220px;
  background: url(bg_top.gif) no-repeat 0 0;
}

.lame_box-inner {
  padding: 20px;
  background: url(bg_bottom.gif) no-repeat 0 100%;
}

/* A single HTTP request? How delightful! */

.cool_box,
.cool_box-shim {
  background: url(bg.gif) no-repeat 0 0;
}

.cool_box {
  width: 180px;       /* Width of the box / bg graphic, minus the padding */
  padding: 20px;      /* Everyone loves padding! */
  
  position: relative;
}

.cool_box-shim {
  height: 20px;       /* Change this to a number <= the bottom padding */
  
  background-position: 0 100%;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  
  _padding: 0 20px;   /* Change the 20px to whatever padding the parent box has. */
  _bottom: -1px;      /* Without this, sometimes you see a line at the bottom in IE6. */
  _width: 100%;       /* Another IE6-only "fix" */
}

/* What's this? Another, totally different looking box
   in the same HTTP request? No way! */

.cool_box_alt {
  background-position: -220px 0;
}

.cool_box_alt .cool_box-shim {
  background-position: -220px 100%;
}

/* This stuff isn't really important, it just helps make the example look pretty. */

.box {
  float: left;
  margin-right: 10px;
}

.box h3,
.box p {
  margin: 0 0 0.6em;
}