January 2, 2012

Equal Height Columns with Gutters

Equal Height Columns with CSS Tables

Have you ever used a background image or extra markup to create the illusion of equal height divs?

Sometimes we want columns with equal heights for a visual effect, but we don’t always know the height of our content.

CSS Table Values

HTML tables already match neighboring cell heights. Like a spreadsheet, if a cell height changes, all of the cells in that row inherit the height. Unfortunately block level elements don’t share heights with their neighbors, making this tough to do with divs alone. However, we can apply a few CSS table values to block level elements, which will emulate a table without the <table> markup.

Ruled Columns

Here’s the most basic example; just a container div and two nested divs, each with content of varying height. For visual effect, the columns have vertical rules:

Equal Height Columns with Vertical Rules

.table_container {
    display: table; }
.cell {
    display: table-cell;
    border-left: 1px solid #abb8b0;
    padding: 0 30px;
    width: 258px; }
.table_container > :last-of-type {
    border-right: 1px solid #abb8b0; }

<div class="table_container">
    <div class="cell">
        <!-- insert content -->
    </div>
    <div class="cell">
        <!-- insert content -->
    </div>
</div>

View Example

Columns with Gutters

What if we want our columns to look more like boxes with a gutter between them? Table cells can’t have margins, but we could add a div for the gutter:

Equal Height Columns with Gutters

.table_container {
    display: table; }
.cell {
    display: table-cell;
    border: 1px solid #809e9c;
    padding: 10px 30px;
    width: 258px;
    background: #fff; }
.gutter {
    display: table-cell;
    width: 30px; }

<div class="table_container">
    <div class="cell">
        <!-- insert content -->
    </div>
    <div class="gutter"></div>
    <div class="cell">
        <!-- insert content -->
    </div>
</div>

View Example

Remove the Last Gutter in a Loop

Say we want to include this markup in a loop, possibly for WordPress. Unfortunately the last gutter div will make a mess of things. The solution; simply target and hide the last div:

.table_container > :last-child {
    display: none; }