I was recently reading an article over at Smashing Magazine about new CSS techniques. One of them was about columns with equal heights and a border. The solution presented requires a background image to be used to fake the gap between the two columns. As I prefer to stay away from images and control the layout with straight CSS, I took a shot at this without any images. This is what I came up with.
Basically I’m using an empty DIV that’s absolutely positioned and with an absurd height value (999,999 pixels) to fake the gap between the two columns rather than use a background image. I then wrap everything in another DIV and set the overflow value to hidden. This hides everything but the bit of that very tall DIV needed to produce the effect. I’m basically clipping the very tall DIV and the clipping is done dynamically (based on the height of the content). The advantage with this solution is that I can control the color of the borders and background with just CSS — I don’t have to create a new image every time I change my color scheme. The downside is you need a couple star-HTML hacks for IE 5 and 6, plus you have to add extra markup in your HTML document that serves no purpose other than to create visual layout objects (which HTML purists feel is wrong, and I kind of agree with them).
Why do we have to fake the visual appearance of two columns and why is it so difficult?
HTML block elements that have no height value explicitly defined (such as via the
height CSS property) will be take whatever height is needed to contain all its children. So if you’ve got a very large image inside a block element, the element will grow very big — just enough to contain the image. If a small image is placed inside a block element, the element will only grow a little bit, just enough to fit the small image.
So create two block elements that will be our columns. Float them left so they sit next to each other. Now put a border around them. What you will see is that the block elements will only be as tall as the content (the text) inside each column. The columns will not be equal height (unless you’ve put the same content into both block elements).
If you want to create the appearance of two columns with the same height, you’ll have to fake it.
Put your columns inside another block element. Your left and right columns will still have different heights, but the block element that contains the columns will grow as tall as it needs to contain both columns, in other words it will grow to be as tall as the tallest column. With this you now have an element you can apply some CSS to which you know will always be as tall as the tallest column in your web page.
What CSS is that?
Depends. A common approach is to set the background color of the block element that contains the two columns (let’s call it a wrapper since it wraps around the columns) to the color you want your left-hand column’s background to be. Then create a border on the wrapper set to the width of the right-hand column and set the color of that border to the color you want the right-hand column’s background to be. You can then use CSS to position that right-hand column over the border of the wrapper. To the viewer it appears as if there are two separate columns with different backgrounds. You can see an example of this in action in my Skidoo Redux layout.
The trick I presented earlier in this post can then be used to add a border around each column.
But Skidoo already has borders around its columns.
Yes, but those columns share borders with other columns. The trick I present here allows each column to have its own set of borders, not shared with any other column (in other words, there’s a gap between the columns). That’s what makes this trick different.