Matching Boxes
11 May 2006
Moving from table layouts to CSS-based layouts, we occassionally need to recreate the effect of boxes of content that remain the same size, even when they contain different amounts of text.
Using table cells for layout, its very easy to ensure that the two boxes will always exactly the same height as, no matter how much text is placed within each box, the height of the row expands to contain the content.
However, in a CSS-based layout, without a fixed height applied, each box will be just big enough to contain the text placed within it and therefore, if one box contains more text than the other, we end up with something like this:
This is Box A.
This box contains more text than Box B.
We want Box B to “stretch” to be the same height.
This is Box B.
This box contains less text than Box A.
But what we actually want is this:
This is Box A.
This box contains more text than Box B.
We want Box B to “stretch” to be the same height.
This is Box B.
This box contains less text than Box A.
In this example, the boxes are fixed at 150 pixels wide with a 15 pixel gutter between them and have a light grey border, 1 pixel wide, on all sides.
How can we ensure that both boxes will be the same height?
Here’s the XHTML code for the boxes:
<div class="boxwrap">
<div class="boxa">
<h4>This is Box A.</h4>
<p>This box contains more text than Box B.</p>
<p>We want Box B to "stretch" to be the same height.</p>
</div>
<div class="boxb">
<h4>This is Box B.</h4>
<p>This box contains less text than Box A.</p>
</div>
</div>
Simple, now for the CSS.
Starting with the boxes themselves (i.e. the inner divs), we know that they both need to be the same width and, because they need to be side by side, we’re going to float them to the left. We’ll also add some padding to give our text room to breathe. Our gutter is provided by applying a right margin on “boxa”.
.boxwrap div {
margin: 0;
width: 150px;
float: left;
}
.boxwrap .boxa {
margin-right: 15px;
}
.boxwrap h4, .boxwrap p {
padding: 5px;
}
Next, we start adding borders. The top border is applied to the individual boxes, but we add a left and right border to our containing “boxwrap” div, which is effectively going to become our table row. (If we were to add the top border to “boxwrap” rather than the individual boxes, we’d get a continuous line with no gap for the gutter.) We’re also floating the boxwrap div to the left to ensure that it always contains its child elements.
.boxwrap {
margin: 0;
float: left;
border: 1px solid #ddd;
border-width: 0 1px 0 1px;
}
.boxwrap div {
margin: 0;
padding: 5px;
width: 150px;
float: left;
border-top: 1px solid #ddd;
}
.boxwrap .boxa {
margin-right: 15px;
}
.boxwrap h4, .boxwrap p {
padding: 5px;
}
Which gives us:
This is Box A.
This box contains more text than Box B.
We want Box B to “stretch” to be the same height.
This is Box B.
This box contains less text than Box A.
Here’s a version of the boxes with different coloured borders applied to our inner divs (red) and boxwrap div (blue), to illustrate where each of our borders comes from:
This is Box A.
This box contains more text than Box B.
We want Box B to “stretch” to be the same height.
This is Box B.
This box contains less text than Box A.
We can see that our boxes are starting to look as though they are the same height, but what about the bottom and “facing” borders?
Borrowing a technique we’ve all seen many times for making a column continue for the full length of a section or page, an image will be used to create the missing borders.
Simply create an image with lines (borders) of the same colour and leave a 15px gutter between them. Remember to make the image tall enough to cover the maximum amount of text that will be placed in the boxes… and then make it taller again, just to be safe. The image we’re using in this example can be found here.
Add this image as the background of the “boxwrap” div and position it at the bottom of the div.
Finally, to play nice with Internet Explorer, we add “display: inline;” to our floated elements, giving us our finished CSS:
.boxwrap {
margin: 0;
float: left;
display: inline;
border: 1px solid #ddd;
border-width: 0 1px 0 1px;
background: url(/images/borders_img.gif) no-repeat bottom;
}
.boxwrap div {
margin: 0;
width: 150px;
float: left;
display: inline;
border-top: 1px solid #ddd;
}
.boxwrap .boxa {
margin-right: 15px;
}
.boxwrap h4, .boxwrap p {
padding: 5px;
}
And our boxes are complete (with not a single script in sight):
This is Box A.
This box contains more text than Box B.
We want Box B to “stretch” to be the same height.
This is Box B.
This box contains less text than Box A.
Of course, they’re not very exciting but you could easily spice things up by adding details to the background image used to create the missing borders.
Need to create boxes with variable width as well as height? Just make your “border” image wider. The only caveat is that the gutter between the boxes must be a fixed width, but that shouldn’t be hard to work around.
Article Tags: boxes, height, layout, style, tips and tricks, web, xhtml, css
About Citrus Skies
Citrus Skies is a small web design studio located in Belfast, Northern Ireland, that designs and creates simple, attractive, effective websites. learn more
