Scalable DOM Module With Rounded Corners

I am working on a homepage for this site and several other site improvements. For that work, I wanted a reusable DOM fragment with accompanying CSS that had rounded corners, a slight gradient background, and scaled well. Here is an example of what I designed. The HTML markup is fairly simple:

Example 1: Module HTML Markup

<div class="module">
	<div class="moduleHeaderOuter">
		<div class="moduleHeaderInner"><h3>Header Content Here</h3></div>
	</div>
	<div class="moduleContentOuter">
		<div class="moduleContentInner">Content Here</div>
	</div>
	<div class="moduleFooterOuter"><div class="moduleFooterInner"></div></div>
</div>

The "div.module" element is just a container and can be styled the way you like it, although it will need to be at least as wide as the graphics you use for the right-side of the backgrounds (more on this later). I chose to use 6 divs to manage the background in a scalable, x-browser way. The outer divs render the right side of the background, while the inner divs contain content and render the left side of the content. The background sides have to be separated for two reason: we do not want to use a fixed width for the module content, so the CSS and background images need to be size naive; and the rounded corners backgrounds cannot overlap, or the solid background of one will cover the transparent part of the other.

You can add content to the inner header, which I have done with a sectional h3 tag, and to the inner content. The inner content has no height constraints as we are repeating an image with a 1px height, but the header row should only have one line height. I used image spriting for the backgrounds and the header only has 60px of background height, which should be reserved for user-driven font scaling. The footer is only an image of 10px height, so it is currently designed as a placeholder and cannot contain any content (this is to reduce the image size of the sprite). Originally, I used the h3 tag instead of the inner and outer header divs, but in the end I decided to use extra divs because the h3 tag has differing font-sizes from the other wrapper divs, and this way is easier to read and more consistent.

For the background to work, I need three image files: a sprite image for the header and footer (4 images in this sprite, one for each corner), a 1px height image for the left background, and a 1px height image for the right background. The left-side images need to be 2x wider than the intended width of your widest module widget, so that they can scale, while the right-side images need only be 1/4 the width of the left-side images, as they do not need to scale very much. The height of the header sprite is 3x greater than the intended height of the headers in the example, to allow for scaling. If you decide that you want to put content into the footers, simply increase the height of the footer sprites to a value 3x greater than the default height of your footer.

So now that we have the images and the HTML, here is the CSS that puts it all together:

Example 2: Module CSS

div.moduleFooterOuter,
div.moduleContentOuter,
div.moduleHeaderOuter {
	margin-left: 1em;
	margin-right: 1em;
	padding-right: 1em;
}

div.moduleFooterInner,
div.moduleContentInner,
div.moduleHeaderInner {
	padding: 0em 1em; /* this spaces the content away from the module edge */
}

div.module div.moduleHeaderOuter {
    background: transparent url(../images/sprite/module_sprite.gif) no-repeat right -120px;
}

div.module div.moduleHeaderInner {
    background: transparent url(../images/sprite/module_sprite.gif) no-repeat left top;
	padding: 0.2em 1em;
}

div.moduleFooterOuter {
    background: transparent url(../images/sprite/module_sprite.gif) no-repeat right -360px;
}

div.moduleFooterInner {
    background: transparent url(../images/sprite/module_sprite.gif) no-repeat left -240px;
	height: 11px;
}

div.moduleContentOuter {
    background: transparent url(../images/bg/module_bg_right.gif) repeat-y right top;
}

div.moduleContentInner {
    background: transparent url(../images/bg/module_bg_left.gif) repeat-y left top;
}

The outer containers use margins, because the "div.module" class will most likely have a width applied, and IE 6 behaves poorly when you apply a width or height and a margin or padding to an element. The "padding-right" of the outer container is what prevents the background images from overlapping each other. The only other tricky part is the negative positions on some of the backgrounds, which are used to find the right sprite as they are positioned every 120px in module_sprite.gif.

See it all working together in this Module Example.