Fixing the Equal Height Columns Problem (CSS)
Tags: css, webdev, wordpress, antipattern
Published: 2020-01-14 10:08:19


## Overview

The equal height columns problem (or [anti-pattern](https://en.wikipedia.org/wiki/Anti-pattern)) is where we have 2-3 three columns in one row. Each column has a different amount of content. So, the bottom of the columns don’t line up evenly. 

Ideally on a larger display, we want to have each column be the same height. And, we want to have buttons or links at bottom of each column be lined-up at the same level/height across the columns.

Here's the anti-pattern we are getting now.

![Equal Height Columns Problem (Before)](https://thepracticaldev.s3.amazonaws.com/i/sd92rt23nr8xz2w0z9ds.jpg "Equal Height Columns Problem (Before)")

The _equal height_ challenge is not specific to just one WordPress theme. But, I'll be using the Avada WordPress theme (no affiliation) for the code examples. 

More importantly, if you can master this common web design pattern here, you’ll be able to handle it like a pro in other themes (or static sites).

<a name="goals"></a>

## Goals [<a href="#goals">#</a>]

Let's recap our goals. On a laptop and desktop view:

1. We would love to have the content boxes be equal height.

2. Say we have three columns with text and a CTA button in each column. The three CTA buttons will hug the bottom of the text block elements (not the bottom of the equal height columns). This means, the positioning of these buttons are at different heights. I.e, **not** what we want. Instead, We **want** them to all line up evenly across the bottom.

3. We don’t want to be forced to always use the exact amount of text for our content boxes like the Avada demos do. The Avada ThemeFusion demos give the illusion of equal height content boxes in a row. They do this by ensuring all the text in their content boxes have the same amount of characters.

![Avada Theme Demo Simulating Equal Height Columns](https://thepracticaldev.s3.amazonaws.com/i/4mvtq3azhj0zkd7zgsl7.jpg "Equal Heights Illusion - Theme Demos Using Equal Text to Simulate Equal Heights")

_Above: The Equal Heights Illusion - Avada Theme Demos Using Equal Text to Simulate Equal Heights_

Our solution should look something like this.

![Equal Heights Problem Solved](https://thepracticaldev.s3.amazonaws.com/i/f2l6lr9rwqt5kb8zlml4.jpg "Equal Heights Problem Solved")

### Side by Side Before/After

{% codepen https://codepen.io/marklchaves/pen/QWwxJOP %} 

Note: Please log in to your CodePen account to view if the pen doesn't show up at first.

<a name="attempts"></a>

## Our First Two Attempts [<a href="#attempts">#</a>]

If we didn't know anything about the equal height columns anti-pattern, we naively would try these two approaches:

### First Try - One Row and One Column of Content Boxes

1. Create one row with one column.
2. Inside the **one** column, add a Content Boxes Element.
3. Create three items inside the Content Boxes Element.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/becalii9sbjtqkbfvtf9.jpg)

_Above: One Wide Column (yellow) with One Content Boxes Element that has Three Items (green)_

### Second Try - One Row with Three Columns with One Content Box Each

1. Create one row.
2. Enable the Set Columns to Equal Height setting for the row.
3. Create three columns (1/3 width each).
4. In each 1/3 column, create one Content Boxes Element.
5. Create one item in each of the Content Boxes Element.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/6w0fwrlol6hn617ucsrg.jpg)

_Above: Three Columns (yellow) with Three Content Boxes (green)_

As you've probably have noticed, neither approach works.

<a name="solution"></a>

## Solution [<a href="#solution">#</a>]

What’s the solution? One solution involves using the First Try method (above) and writing custom CSS to:

1. Perform a media query (responsive design).
2. Set a fixed height for the content boxes.
3. Push the buttons down to the bottom using absolute positioning.

I know you are wondering. How many lines of code will this cost me? Six!

```css
/* Only do this fancy stuff for devices larger than a tablet. */
@media only screen and (min-width: 1025px) {
  .content-container {
    min-height: 500px; /* Change this to what you need. */
  }
  /* Ground the CTA button. */
  .fusion-button-wrapper {
    position: absolute;
    bottom: 5px;
  }
}
```

### Instructions

1. Add this CSS code to your [Custom CSS code editor](https://medium.com/@marklchaves/adding-custom-css-to-your-wordpress-website-how-to-guide-a50b474af36d) for the page that has your content boxes.
2. Adjust the `min-height` value to what works for you.
3. Click Update to save the page.
4. Reload the page (clear caches if needed) to view the changes.

### Recap of the Code

OK. Here's what this CSS is doing.

1. A media query to force equal heights only for larger devices. For anything smaller than `1025px`, the design becomes responsive by stacking the content boxes.
2. A `min-height` property for the content boxes to ensure each box has the same height inside their _parent_ containers.
3. Absolute positioning on the button components to force them to the bottom of their container columns.

<a name="flex"></a>

### Flex Version [<a href="#flex">#</a>]

What's that you say? Where's the CSS3 flexbox version?!

```css
/* Only do this fancy stuff for devices larger than a tablet. */
@media only screen and (min-width: 1025px) {
  .content-container {
    display: flex;
    flex-flow: column;
    flex: 1 200px;
    min-height: 450px; /* Change this to what you need. */
  }
  /* Need to force the width for the paragraph for some reason. */
  .content-container p {
    min-width: 300px !important;
  }
  /* Ground the CTA button. */
  .fusion-button-wrapper {
    flex: 1 100px;
    display: flex;
    align-items: flex-end; /* Ground the button . */
    justify-content: left; /* left | center | right */
  }
}
```

#### Vanilla Flexbox Example on CodePen

This solution is more elegant than the Avada one above. Instead of worrying so much about the button, I use `flex: 1` for the middle content section. With that 1-line of CSS, the positioning of the button towards the bottom comes for free.

`flex: 1` is shorthand for flex-grow of a factor of 1. I.e., take up all the _remaining_ space by 1 factor.

Thanks to Angus for sharing this technique with me! :-)

{% codepen https://codepen.io/marklchaves/pen/xoNPEQ %}

Note: Please log in to your CodePen account to view if the pen doesn't show up at first.

<a name="conclusion"></a>

## Recognise the Anti-pattern [<a href="#conclusion">#</a>]

I've seen the equal height columns issue come up enough times&mdash;hence this post. Learn to recognise the **anti-pattern**. Then, you can be a _rock star_ by applying the **design patterns** I've shared above.

Share & enjoy!