Create Columns with Equal Heights

Roy AngerUpdated:

Tags:

A common request we see on the X Theme Users forum is to create equal height columns in Cornerstone. We’re going to cover three ways to do this in X. Yup, three ways!

Method 1: Flexbox

A little bit of CSS, added either to the page if you want it for one page, or to the Customizer if you want it for multiple pages, gives you the building block you need. Then add the class ‘flexmethod’ to the row (not the column). Its quick. Unlike the JavaScript method it shows equal height columns immediately. The downside to this is that if you have multiple rows this is applied to, the height of the columns will only be equal within each row, preventing you from achieving a proper grid layout if that is your goal.

.flexmethod {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-line-pack: stretch;
      align-content: stretch;
  -ms-flex-wrap: wrap;
      flex-wrap: wrap;
}
.x-container:before {
  content: normal;
}
March 24, 2017
Some Safari users have reported problems with the flexmethod CSS. It appears to be related to the :before pseudo element. As such, we’ve added to the above CSS with a fix.

Flex Method in Action

Sample Headline

Bacon ipsum dolor amet landjaeger hamburger sirloin, porchetta brisket cupim prosciutto sausage ball tip capicola boudin bacon

Sample Button

Sample Headline

Bacon ipsum dolor amet landjaeger hamburger sirloin, porchetta brisket cupim prosciutto sausage ball tip capicola boudin bacon bresaola. Beef doner ball tip sausage turducken t-bone cow, pork belly alcatra beef ribs shoulder pastrami pork loin. Ground round pancetta bresaola burgdoggen pig rump.

Sample Button

Sample Headline

Bacon ipsum dolor amet landjaeger hamburger sirloin, porchetta brisket cupim prosciutto sausage ball tip capicola boudin bacon

Sample Button

Some of you might have also noticed that buttons are aligned to the bottom. As bonus, I’ve added that CSS to the post. We have .container and a .item-button. Add the first as a class to the column and the second as a class to the button.

.container {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex; 
  -webkit-box-orient: vertical; 
  -webkit-box-direction: normal; 
      -ms-flex-direction: column; 
          flex-direction: column;
}
.item-button {
  margin-top: auto;
}
.x-container:before {
  content: normal;
}

Method 2: JavaScript

We can achieve the same result with some Javascript. The benefit of js is that you can apply equal height columns to both block and table layouts, as well as apply advanced math or formulas across several rows. A big plus for the javascript method is that the height of the columns will be equal across all rows, giving a grid-like effect. The disadvantage to this is the initial load time. Although only milliseconds on fast connections, the columns will initially appear at different heights and then a moment later will adjust heights. Just like the previous CSS method, you can place this JavaScript in either the page’s Custom JS section of the Customizer’s Global JS section. Once done, add the class jsmethod to the rows you want it applied to. This script was originally provided by Themeco and edited by Michael Bourne to allow window resizing and respect padding within the column.

(function($){
  $(window).on('ready load resize', function(){
    var max = 0,
        mobile = $(window).width();
    $(".jsmethod .x-column").css('min-height', 'inherit');

    if ( mobile > 767 ){
      $(".jsmethod .x-column").each(function(index, el) {
        if( $(this).outerHeight() > max ){
            max = $(this).outerHeight();
        }
      });
      $(".jsmethod .x-column").css('min-height', max);
    }
  });
})(jQuery);

Need to equalize more than one row on a page, and want those rows to have independent heights?

The code above works great, but if you apply the jsmethod class to more than one row, they will all end up the same height. If you’d like to change that, use this code instead:

(function($){
  $(window).on('load resize', function() {
    $(".jsmethod").each(function(index, el) {
      var max = 0,
      mobile = $(window).width();
      $(this).find(".x-column").css('min-height', 'inherit');
      $(this).find(".x-column").css('height', 'auto');
      if ( mobile > 767 ){
        $(this).find(".x-column").each(function(index, el) {
          if( $(this).outerHeight() > max ){
            max = $(this).outerHeight();
          }
        });
      }
      $(this).find(".x-column").css('min-height', max);
    });
  });
})(jQuery);

JavaScript Method in Action

Sample Headline

Bacon ipsum dolor amet landjaeger hamburger sirloin, porchetta brisket cupim prosciutto sausage ball tip capicola boudin bacon

Sample Headline

Bacon ipsum dolor amet landjaeger hamburger sirloin, porchetta brisket cupim prosciutto sausage ball tip capicola boudin bacon bresaola. Beef doner ball tip sausage turducken t-bone cow, pork belly alcatra beef ribs shoulder pastrami pork loin. Ground round pancetta bresaola burgdoggen pig rump.

Sample Headline

Bacon ipsum dolor amet landjaeger hamburger sirloin, porchetta brisket cupim prosciutto sausage ball tip capicola boudin bacon

Bonus: Marginless JavaScript Grid

This uses the same code as above, but will also set the proper width of each column based on how many are present in the first row, and remove the margins. This is perfect for making your own grid-like layout. Simply create as many rows as you want with the class “jsmethodgrid” on each row you want the effect applied to. Make the same number of columns in each row.

(function($){
  $(window).on('ready load resize', function(){
    var max = 0,
        mobile = $(window).width(),
        numChildren = $('.jsmethodgrid').first().children().size();

    $(".jsmethodgrid .x-column").css('min-height','inherit');

    if ( mobile > 767 ){
      $('.jsmethodgrid .x-column').css({ 'width' : 100/numChildren + '%', 'margin': 0 });
      $(".jsmethodgrid .x-column").each(function(index, el) {
        if( $(this).outerHeight() > max ){
            max = $(this).outerHeight();
        }
      });
      $(".jsmethodgrid .x-column").css('min-height', max);
    } else {
	    $('.jsmethodgrid .x-column').css('width','100%');
    }
  });
})(jQuery);

Method 3: Marginless Column Method

Want to know what code you need for marginless columns? None. That’s right. The sample below has no JS and no CSS. Marginless columns are automatically the same height. Depending on your content you may be able to use this method your advantage. In the sample below I’ve enabled the same border on all columns and the row. This gives a uniform look to the border.
Marginless columns can be set in the row element in Cornerstone, right below the column container toggle.

Marginless Method in Action

Sample Headline

Bacon ipsum dolor amet landjaeger hamburger sirloin, porchetta brisket cupim prosciutto sausage ball tip capicola boudin bacon

Sample Headline

Bacon ipsum dolor amet landjaeger hamburger sirloin, porchetta brisket cupim prosciutto sausage ball tip capicola boudin bacon bresaola. Beef doner ball tip sausage turducken t-bone cow, pork belly alcatra beef ribs shoulder pastrami pork loin. Ground round pancetta bresaola burgdoggen pig rump.

Sample Headline

Bacon ipsum dolor amet landjaeger hamburger sirloin, porchetta brisket cupim prosciutto sausage ball tip capicola boudin bacon

Michael created a sample page with all 3 methods. You can take a look at them there without all the text and clutter of this post.

Have a question or a comment about this article? Click here!
About the Author

Roy Anger

Hey everyone. I made my first website way back in about 95, before PHP, Wordpress, CSS and even tables. I love the flexibility and framework available in X, and love working with X on client sites. Aside from Wordpress, I love spending time with my two girls (girlfriend and chocolate Lab), trying to be a decent photographer and generally relaxing.

Share this Tip!