Thursday, 9 June 2011

4 Methods For Creating Equal Height Columns In CSS | Van SEO Design

4 Methods For Creating Equal Height Columns In CSS | Van SEO Design


4 Methods For Creating Equal Height Columns In CSS

Posted: 09 Jun 2011 05:30 AM PDT

One of the few things that isn’t as simple to do with css as it should be is creating columns of equal heights. A variety of methods do exist, each with its pros and cons and I want to present 4 methods here.

Let’s think for a moment about what we mean by equal height columns.

We generally don’t mean that we want the content inside each column to be of equal height. If that were the case there really isn’t a problem as the height of the columns will naturally be the same height.

What we really mean by equal height columns is having the columns look as though they’re of equal height when the content inside isn’t.

We can achieve that by making the css backgrounds behind the column appear to be of equal height. Ultimately we’re faking equal heights.

For those of you wanting to get directly to the demos and code you can click any of the images above the sections below and be taken to the appropriate demo.

Equal height columns with faux Columns

Faux Columns

Faux columns have been around a long time. 2004 to be exact. For that same long time they were and maybe still are the deFacto method for creating columns of equal height.

It’s a simple trick using a background image that’s repeated vertically. An example of this repeating image is seen below. I’ve increase the height so you can see it.

Faux columns background

The image is usually created as a single px in height and it’s width will match the width of your layout. Where one column becomes another in the layout, the faux column image will change as well.

The html

For this example we’ll use html that’s similar to what we’ve been working with the last few weeks, though I’ll skip the header and footer to focus on the columns.

 <div id="container"> 	<div id="sidebar"> 		<p>Sidebar</p> 	</div> 	<div id="content"> 		<p>Main content</p> 	</div> </div> 

You could use the body as the container, but I’m choosing to use a container div so you can see that this technique can work for setting up columns inside a part of your overall layout in addition to the overall layout itself.

The css

 #container { 	width:960px; 	margin:0 auto; 	background: url("faux-columns.png") repeat-y; 	overflow: hidden } #sidebar { 	float:left; 	width:340px; } #content { 	float:left; 	width:620px; } 

The css here is pretty simple. Floating and setting widths on #sidebar and #content should be familiar to you by now as well as setting the width and margin on #container.

What’s new here is setting the faux-column background image on the container and using overflow: hidden on the container.

We need to set the overflow property to ensure the container div doesn’t collapse. Because everything inside is floated we need to force it back open.

The container will then always be the same height as the longer of the 2 columns and the background image will make it appear as though the shorter column is also the same height.

This method works best for fixed width layouts though it can work with more fluid layouts as well.

You also aren’t limited to a simple color change in backgrounds. Borders, shadows, patterns, etc. can be added by adding them in the appropriate place on the faux-column image.

For patterns you might choose to create an image more than 1px in height.

Pros:

  • Easy to set up
  • Work regardless of which column is the longer or shorter

Cons:

  • Requires an image, which requires an additional http request
  • Any change to the layout requires the image be reworked
  • Need to know what your layout will look like in advance to create the image

Pseudo method for creating equal height columns

Pseudo Columns

I’ve never cared for faux columns. Not because it’s a bad method, but because I have a thing about never using an image for a solid background color.

Because of that I developed my own method for achieving equal height columns, which for lack of a better term I’ll call pseudo columns.

It works similarly to faux columns as it involves setting a background on the container. It’s not a general approach to equal height columns and has a very limited use case, but when you encounter that use case it works well and easily.

The html

We’ll use the same html as the faux column method above.

 <div id="container"> 	<div id="sidebar"> 		<p>Sidebar</p> 	</div> 	<div id="content"> 		<p>Main content</p> 	</div> </div> 

Once again no header and footer so we can focus on the columns.

The css

The css is again quite simple. I’ve gone with a fluid layout here for variety, but you could just as easily set this up to be fixed width.

 #container { 	background: #555; 	overflow: hidden } #content { 	float:left; 	width:75%; 	background:#eee; } #sidebar { 	float:left; 	width:25%; 	background:#555; } 

Other than using % instead of px, you’ll notice that here I’ve set the background colors on #content and #sidebar. You’ll only need to set it on whichever column will be longer, but here I’ve set it on both.

The main change from faux columns is instead of a background image we set a background color. It’s the same principle in that we’re allowing the background of the container to show through beneath the shorter columns.

The limitation is we need to know which column will be shorter in advance and ideally that same column would be shorter on every page of the site.

That sounds like a pretty big limitation, but I find in practice one of the two columns is usually shorter across most, if not all, pages and for those pages where it might not be the case, it’s easy enough to add a little more or less content to make it so.

Pros:

  • Easy to set up
  • Easy to maintain

Cons:

  • Harder to implement on more than 2 or 3 columns
  • Requires you know the relative heights of columns in advance
  • Doesn’t work as well when different columns are longer or shorter on different pages

This method is far from perfect, but you might be surprised how often it can be applied in practice.

Equal height columns with borders and negative margins

Borders and Negative Margins

This is a method I came across not too long ago on a Smashing Magazine article by Thierry Koblentz, though I later found an article by Alan Pearce on A List Apart written a few years ago detailing the same method.

It uses borders and negative margins to give the appearance of the equal height columns.

The html

Nothing new in the html here compared to what we’ve seen above. In his article Thierry uses the body as the container, but I’ll stick to using a container div as is my usual practice.

 <div id="container"> 	<div id="sidebar"> 		<p>Sidebar</p> 	</div> 	<div id="content"> 		<p>Main content</p> 	</div> </div> 

The css

The css is where things get interesting. The container is just being used to fix the width and center the layout. The interesting stuff happens on #content and #sidebar.

 #container { 	width:960px; 	margin: 0 auto; } #content { 	float:left; 	width:700px; 	border-left: 260px solid #555; } #sidebar { 	float: left; 	width:260px; 	margin-right: -260px; 	position: relative; } 

All the background colors in this method are set on the #content column. We set it’s background as normal and then give it a left border equal to the width of the sidebar. We also set the border color to what we want the sidebar background to be.

If we stop here you’ll see both columns displayed where you want, however our border-left has pushed the actual sidebar off the page and we need to bring it back.

First we give the sidebar a negative right margin equal to its width (or the width of the left border of the content, which are the same). That will bring the sidebar back to where we want, but it still isn’t visible.

The problem is in the stacking order of the 2 divs. #container is sitting on top of #sidebar so we need to move #sidebar to the front. We do that by adding position: relative to the sidebar and now it’s content is visible.

Pros:

  • Works regardless of which columns is longer or shorter
  • Easy to set up once you understand how it works
  • Easy to maintain

Cons:

  • Sidebar width needs to be fixed as border-width only accepts absolute measurements
  • Negative margins can potentially trip up some older versions of IE

I’d encourage you to read both articles I linked to above as they offer more details than I am here. Both contain code for using this method with a third column and Thierry’s article talks about setting up borders between the columns.

Equal height columns with offset containers

Offset Columns and Containers

This last method is one created by Matthew James Taylor. Of all the methods presented here this one will work under the most use cases.

I’ve saved it for the end since it’s a little more complex and you might need to read through it a few times to understand how it works.

The html

The html is similar to what we’ve seen above though you’ll note an extra container div to what we’ve seen before.

 <div id="container-outer"> 	<div id="container-inner"> 		<div id="sidebar"> 			<p>Sidebar</p> 		</div> 		<div id="content"> 			<p>Main content</p> 		</div> 	</div> </div> 

As with the other methods we’ll use these containers to set background colors that will appear as though they belong to our columns.

The css

There’s a lot more going on here than what we’ve seen to this point. Both #sidebar and #content are floated left and given a width, but beyond that just about everything else is new.

The key to this method is the idea that a floated container will always be the same height as its floated content. By floating all of our columns inside all of the floated containers we ensure our container divs will always be equal in height to the tallest column.

 #container-outer { 	float:left; 	overflow: hidden; 	background: #eee; } #container-inner { 	float:left; 	background: #555; 	position: relative; 	right:75%; } #sidebar { 	float: left; 	width: 25%; 	position: relative; 	left: 75%; } #content { 	float: left; 	width: 75%; 	position: relative; 	left: 75% } 

The first step here is to float both the columns and the containers. I have everything floated to the left, but the direction isn’t important. Use whatever direction you need for your layout.

The next step is setting backgrounds on the 2 container divs. Here I’ve set the background on the inner container to be the one we want on the sidebar and the outer container background to what we want on the main content.

If we stop here we’ll only see the background on the inner div since it’s higher in the stacking order than the outer div.

We need to a little css positioning to shift the inner div so it shows only where we want the sidebar to display. That will allow the background on the outer div to show through behind where we want the content column to display.

 #container-inner { 	position: relative; 	right: 75%; } 

We position the inner column and then set it’s right value to be 75% which is the same as the width of our content column.

Our backgrounds are now in place, however the content of both columns has also shifted 75% to the left. We need to shift it back into place.

 #sidebar {     position: relative;     left:75% } #content {     position: relative;     left:75% } 

Once again we use relative positioning and because the content in both columns has been shifted 75% to the left we need to shift it back 75% to the right. We do that by setting the left value to 75%.

Now everything is back where it should be.

Pros:

  • Works regardless of which column is longer or shorter
  • Works with any kind of layout (fixed, fluid, elastic, etc)
  • Can handle as many columns as you want

Cons:

  • A little more difficult to understand at first
  • Requires additional and non-semantic container divs

Overall this is the most foolproof method and the one guaranteed to work for any use case. I’d encourage you to play around with this one to really understand it and read through Matthew’s article a few times.

Matthew’s article walks through a 3 column layout and he has demos for both 4 and 5 columns as well. I chose to present a 2 column layout in the hopes it would make the concepts easier to understand.

Additional Resources

By no means are these the only methods for creating equal height columns. Chris Coyier shared a several other methods on CSS Tricks a few months back that you may prefer over those presented here.

There are also plenty of other methods you can find with a little searching. Between this article and Chris’ I think most of the more common methods are covered.

Two standing columns at the ruins of a Roman theatre in Arles

Summary

Equal height columns are a desirable design trait, but they haven’t always been easy to create with css layouts. Ideally we’d be able to use something like height: 100% and be done with it, but for now we can use any of the methods mentioned above.

Faux columns are easy to set up, but they require an extra http request for the image and any change to the layout requires a new image.

Pseudo columns are even easier, but have a limited use case where the relative heights of both columns are known and consistent across pages.

Borders and negative margins are relatively easy to work with, require no foreknowledge of column heights and better adapt to multiple columns. They require one column be fixed width.

Offset columns and containers work across the most cases. They require no foreknowledge of column heights and can work with as many columns as you want. The method is a little more complex than the other methods.

In time I expect a much simpler standard css solution, but until then these 4 methods should suffice for your project.

Do you design equal height css column layouts often? What method for creating the columns to use when you do?