CSS Equal height colums

Most multi-column layouts use multiple float:left divs inside a container div.

Lets have a look at a simple main column and sidebar column layout:

HTML:

<div class="main">
    <div class="container clearfix">
        <div class="content">
            <section>
                <h1>This is the Main Content</h1>
                <hr>
                <h2>A sub heading</h2>
                <p>Lorem ipsum dolor sit amet, consectetur...</p>
                <p>Lorem ipsum dolor sit amet, consectetur...</p>
                <p>Lorem ipsum dolor sit amet, consectetur...</p>
                <p>Lorem ipsum dolor sit amet, consectetur...</p>
                <p>Lorem ipsum dolor sit amet, consectetur...</p>
                <p>Lorem ipsum dolor sit amet, consectetur...</p>
            </section>
        </div>
        <div class="sidebar">
            <aside>
                <h2>This is a sidebar</h2>
                Sign up to the newsletter!
            </aside>
        </div>
    </div><!-- /.container -->
</div><!-- /.main -->

Go here and paste the above code into the HTML pane.

Method 1

This first method uses margins, paddings, and overflow to force the columns to be equal heights. The methodology entails setting a big enough padding at the bottom of each floated element, and countering it with an equal negative margin at the bottom of the same elements. The trick is to set the overflow on the parent container to hidden. We’re going to assume a fixed sidebar and fluid content container for this example.

CSS:

.main .container {
    padding-right: 330px;
    overflow: hidden;
}
.content {
    float: left;
    width: 100%;
    background-color: red;
}
.sidebar {
    float: right;
    margin-right: -330px;
    width: 300px;
    background-color: blue;
}
.content,
.sidebar {
    padding-bottom: 99999px;
    margin-bottom: -99999px;
}
section,
aside {
    padding: 30px
}

Paste the above code into the CSS pane and inspect the results.

This could be extended to multiple rows for a more grid-like layout instead of just two columns. You can also use fluid width columns using percentage values if you want.

If you want to stick with fixed width columns, simple media queries will set us up for a responsive flow on small screen devices:

CSS:

@media all and (max-width: 840px) { 
    .main .container {
        padding: 0 30px;
        overflow: visible;
    }
    .content {
        float: none
    }
    .sidebar {
        float: none;
        margin-right: 0;
        width: 100%;
    }
    .content,
    .sidebar {
        padding-bottom: 0;
        margin-bottom: 0;
    }
    .content {
        margin-bottom: 30px
    }
}

Append the above code to the existing code in the CSS pane. Resize the browser to inspect the results.

We simply remove the floats to revert to normal flow (where the sidebar sits below content, both inside container) and set the sidebar width to 100%.  So now we have container with no width set and two children (content and sidebar), each with width set to 100%.

Go here for a live demo of method 1.

Method 2

This version makes use of the pseudo class :after. It also makes use of the fact that this pseudo class places content right after the element. It requires a hint of math to make things line up, but it reacts appropriately when you resize the browser etc.

The parent container will have a relative positioning, and the pseudo elements will take on an absolute positioning, with 100% height. We’ll only position the pseudo elements the required distance from the left and right of the container though. The container will have a hidden overflow applied as well.

CSS:

.main .container {
    padding: 0 360px 0 30px;
    position: relative;
    overflow: hidden;
}
.content {
    float: left;
    width: 100%;
    background-color: red;
}
.sidebar {
    float: right;
    margin-right: -330px;
    width: 300px;
    background-color: blue;
}
.content:after,
.sidebar:after {
    display: block;
    position: absolute;
    height: 100%;
    content: "";
    background-color: blue;
}
.content:after {
    left: 30px;
    right: 360px;
}
.sidebar:after {
    right: 30px;
    width: 300px;
}
section,
aside {
    padding: 30px
}

The left and right positioning of the content and sidebar are 30px to compensate for the padding on the parent container.  To make it responsive we again will need some media queries.

CSS:

@media all and (max-width: 840px) { 
    .main .container {
        padding: 0 30px;
        overflow: visible;
    }
    .content {
        float: none;
        margin-bottom: 30px;
    }
    .sidebar {
        float: none;
        margin-right: 0;
        width: 100%;
    }
    .content:after,
    .sidebar:after {
        display: none
    }
}

Go here for a live demo of method 2.

Method 3

We can apply table formatting to divs.  Copy the following code in the HTML pane:

HTML:

<div class="main">
    <div class="container">

        <div class="table">
            <div class="row">
                <div class="col content">
                    <h1>Section 1</h1>
                    <hr>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam, laborum, repudiandae, soluta sapiente architecto et fugit laboriosam exercitationem error quisquam doloribus veritatis consequatur ipsum consectetur ad maxime obcaecati quod ipsa.</p>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Numquam, sunt, soluta, vero, illo in dolore cum velit aperiam eius quidem ad quasi inventore rerum ab rem itaque et ullam earum.</p>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ullam, laborum, repudiandae, soluta sapiente architecto et fugit laboriosam exercitationem error quisquam doloribus veritatis consequatur ipsum consectetur ad maxime obcaecati quod ipsa.</p>
                    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Numquam, sunt, soluta, vero, illo in dolore cum velit aperiam eius quidem ad quasi inventore rerum ab rem itaque et ullam earum.</p>
                </div>
                <div class="col sidebar">
                    <h2>Sidebar</h2>
                    <p>Subscribe to the newsletter!</p>
                </div>
            </div>
        </div>

    </div>
</div><!-- #main -->

CSS:

*, *:before, *:after {
    box-sizing: border-box;
}

.main .container {
    padding: 0 0;
}
.table {
    display: table;
    border-collapse: separate;
    border-spacing: 30px 0;
}
.row {
    display: table-row;
}
.col {
    display: table-cell;
    background-color: #fff;
    padding: 30px;
}
.col.sidebar {
    width: 300px;
    background-color: blue;
}

.col.content {
    background-color: red;
}

And the media queries to make it responsive:

CSS:

@media all and (max-width: 840px) { 
    /* demo 3 */
    .main .container {
        padding: 0 30px;
        width: 100%;
    }
    .table {
        display: block;
    }
    .row {
        display: block;
    }
    .col {
        display: block;
    }
    .col.content {
        margin-bottom: 30px;
    }
    .col.sidebar {
      width: 100%;
    }
}

Note: ‘box-sizing: border-box’ was used here to specify that elements should have padding and border included in the element’s total width and height.

Go here for a live demo of method 3.

Method 3 – Additional benefit #1

If we only need one row you can skip the row element.  Also, table layout uses equal column height by default.

HTML:

<div class="container">
    <div class="column">Column 1.</div>
    <div class="column">Column 2 is a bit longer.</div>
    <div class="column">Column 3 is longer with lots of text in it.</div>
</div>

CSS:

.container {
  display: table;
}
.column {
  display: table-cell;
  width: 100px;
}

Click here for an example.  Resize the browser window to inspect.

Method 3 – Additional benefit #2

When floating elements it is easy to specify a fixed width, or percentage width, but not proportional widths to fill the available space.  Using table based styling, you can proportionally size the columns to fill the available space dependent on their content:

CSS:

.container {
  display: table;
  width: 100%;
}
.column {
  display: table-cell;
}

Click here for an example.  Resize the browser window to inspect.

Flexbox

The Flexbox Layout (Flexible Box) module (currently a W3C Last Call Working Draft) aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word “flex”).

The main idea behind the flex layout is to give the container the ability to alter its items’ width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space, or shrinks them to prevent overflow.

Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based). While those work well for pages, they lack flexibility (no pun intended) to support large or complex applications (especially when it comes to orientation changing, resizing, stretching, shrinking, etc.).

https://css-tricks.com/snippets/css/a-guide-to-flexbox/

CSS Equal height colums was last modified: May 26th, 2015 by tabcom