Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

Quick Tip: Solving the Equal Height Column Conundrum

by
Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

There's one familiar problem in web design which has been around ever since we moved from the days of table-based design into the CSS era, and that is:

How can I have 100% height backgrounds in my flexible multi-column layout?

There are a few solutions to this dilemma, however the one we're about to cover might be right for your project if you need:

  1. Background images, borders, CSS3 effects etc. applied to your columns
  2. More than three columns
  3. Flexible height and width columns

Let's start with a quick look at the problem.

Default Column Background Behaviour

Pictured below is a simple three column layout, using a standard approach of floating each column to the left. With backgrounds applied in the default fashion, the columns adjust to the height of their content like so:

This is functional, but not quite the most pleasing layout to the eye due to the significant difference in heights.

The HTML for the above places three "column content" elements within a wrapper:

<div class="wrap">
    <div class="content">...</div>
    <div class="sidebar">...</div>
    <div class="sidebar_two">...</div>
</div>

The CSS for these "column content" elements is:

.content {
    width:60%;
    float:left;
    padding: 20px 30px;
    background: #fff;
    color: #6d7072;
}
.sidebar {
    width:20%;
    float:left;
    padding: 20px 30px;
    background: #5f6673;
    color: #ebeef3;
    font-size: 90%;
}
.sidebar_two {
    width:20%;
    float:left;
    padding: 20px 30px;
    background: #434750;
    color: #ebeef3;
    font-size: 90%;
}

A Solution: Pseudo-Elements to the Rescue

When we refer to equal height columns, what we typically want is to satisfy two conditions:

  1. Allow column height to flexibly fit the amount of content therein.
  2. Set uniform background height independently of the amount of content in each column.

In our example above we already have the first condition of flexible height satisfied. However the background styles and flexible height rules are all part of the same class, applied to the same element. Whatever height rules that element follows, the background will follow them too.

Therefore if we want the backgrounds to have different height settings, we will need separate elements we can apply the background styles to along with their own set of height rules. To create these separate elements without adding any extra markup, we're going to use pseudo-elements.

For each column we will use the :before pseudo-selector to generate a separate pseudo-element, to which we will apply background styling. We will then use a combination of absolute positioning and z-index to place these backgrounds behind the content for each column and set them to a uniform height.

The new CSS for each column becomes:

.content, .content:before {
    width:60%;
}
.content {
    float:left;
    padding: 20px 30px;
    color: #6d7072;
}
.content:before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: -1;
    left: 0;
    background: #fff;
}
.sidebar, .sidebar:before {
    width:20%;
}
.sidebar {
    float:left;
    padding: 20px 30px;
    color: #ebeef3;
    font-size: 90%;
}
.sidebar:before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: -1;
    left: 60%;
    background-color: #5f6673;
}
.sidebar_two, .sidebar_two:before {
    width:20%;
}
.sidebar_two {
    float:left;
    padding: 20px 30px;
    color: #ebeef3;
    font-size: 90%;
}
.sidebar_two:before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: -1;
    left: 80%;
    background-color: #434750;
}

Which gives us presentation of nice, even column heights:

How it's Done

In a nutshell what we're doing here is absolutely positioning "background holder" pseudo-elements behind the regular "column content" elements in order to create background styles. 

Because these "background holder" pseudo-elements are absolutely positioned we can tell them exactly where their outer edges ought to be, while still allowing the "column content" elements to be any height or width they need to be.

The .wrap element, its three child elements and their pseudo-elements
Each column element has a corresponding pseudo-element, which acts as the background

Important: Your columns should be inside a parent wrapper (.wrap in this case) set to position: relative; in order for the absolute positioning to work. This should clear after the floating columns to ensure it receives a height value for the backgrounds to stretch to.

Perks and Alternative Approaches

There are a couple of great approaches out there which suggest other ways to solve this problem. If you don't need the specific perks of this approach, you may prefer one of the following solutions.

Flat Colors vs. Background Images and Extra Effects

If you plan to use only flat colors in your backgrounds, then a very clever solution is to apply a horizontal CSS gradient, creating bands of color to line up with your columns. Check out how, thanks to Chris Coyier.

However if your design needs images, borders, CSS3 effects and so on applied to your backgrounds then our "background holder" div technique may be a better fit, e.g.

Fewer Than, or More Than Three Columns

Another very cool solution is to use the pseudo selectors :before and :after on the columns' parent wrapper to create up to three columns with equal height backgrounds. You can read about this technique, explained by Nicolas Gallagher.

On the other hand if you need more than three columns you might want to use our "background holder" technique instead as you can have as many columns as you like. e.g.

Conclusion

Once we see widespread browser support for flexbox it should become pretty straight forward to do things like this without needing to rely on pseudo-elements.

However, between now and then, this is a great way to get the job done. It lets you keep flexible width for responsive layouts, use as many columns as you like and apply any type of background styling. 

Advertisement