Как сделать колонки одинаковой высоты

В этом уроке я приведу различные способы, показывающие как можно сделать колонки одинаковой высоты. Все варианты будут разобраны для двухколоночного макета страницы, но они также будут работать для трёх и более колонок (с небольшой модификацией). Часть примеров реализуется на чистом CSS, другие используют JavaScript. Вы можете посмотреть каждый пример в редакторе Codepen, кликнув по картинке.

1. Псевдоэлемент и абсолютное позиционирование

Суть данного способа следующая: с помощью псевдокласса :after каждой колонке добавляется блок, который залит соответствующим цветом и имеет высоту, равную 100% высоте блока-контейнера. Для блока-контейнера задано свойство overflow: hidden;, которое и обрезает лишнюю высоту.

<header>Шапка страницы</header>
  <div class="container">
    <div class="main-content">
      <div>
        <h1>Основной контент</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
      </div>
    </div>
    <aside>
      <div>
        <h2>Боковая колонка</h2>
        <p>Nullam ac imperdiet mi. In efficitur iaculis erat id mattis...</p>
     </div>          
    </aside>
  </div>
<footer>Подвал страницы</footer>
body {
  margin: 0;
  background: #FAF2D6;
  color: #302E2D;
}
header {
  padding: 30px 60px;
  background: #80C8A0;
}
.container {
  padding: 30px;
  position: relative;
  overflow: hidden;
}
.main-content {
  float: left;
  width: calc(100% - 330px);
  background: #C9CCC8;
}
aside {
  float: right;
  width: 300px;
  background: #EC5A45;
}
.main-content:after, aside:after {
  content: "";
  position: absolute;
  height: 100%;
}
.main-content:after {
  left: 30px;
  right: 360px;
  background: #C9CCC8;
}
aside:after {
  right: 30px;
  width: 300px;
  background: #EC5A45;
}
.main-content div, aside  div {
  padding: 30px 30px 0 30px;
}
footer {
  margin-top: 30px;
  padding: 30px 60px;
  background: #80C8A0;
}
.container:after {
  content: "";
  display: table;
  clear:  both;
}

В медиазапросе, например, для максимальной ширины 860px отменим обрезку содержимого контейнера, обтекание для колонок и скроем содержимое, добавленное с помощью псевдокласса. Ширину колонок сделаем равную ширине блока-контейнера.

@media (max-width: 860px) {
  .container {
    overflow: visible;
    }
  .main-content {
    float: none;
    margin-bottom: 30px;
    width: 100%;
    }
  aside {
    float: none;
    width: 100%;
    }
  .main-content div, aside  div {
  padding: 30px;
}
  .main-content:after, aside:after {
    display: none;
    }
  footer {
    margin-top: 0;
  }
} 

2. Внутренние и внешние отступы

Для каждой колонки устанавливаем нижнее поле padding с большим значением. В этом случае фон колонки будет распространяться на всю высоту поля. Далее задаём отрицательное нижнее поле с таким же значением. С его помощью мы уменьшаем высоту колонки до её фактических размеров, не затрагивая фоновую заливку. Свойство overflow: hidden;, заданное для блока-контейнера, обрезает высоту каждой колонки, ориентируясь на самую высокую.

body {
  margin: 0;
  background: #FAF2D6;
  color: #302E2D;
}
header {
  padding: 30px 60px;
  background: #80C8A0;
}
.container {
  padding: 30px;
  overflow: hidden;
}
.main-content {
  float: left;
  width: calc(100% - 330px);
  background: #C9CCC8;
}
aside {
  float: right;
  width: 300px;
  background: #EC5A45;
}
.main-content, aside {
  padding-bottom: 99999px;
  margin-bottom: -99999px;
}
.main-content div, aside  div {
  padding: 30px 30px 0 30px;
}
footer {
  margin-top: 30px;
  padding: 30px 60px;
  background: #80C8A0;
}

В медиазапросе уберём нижние поля и отступы, отменим обрезку содержимого и установим ширину колонок, равную ширине блока-контейнера.

@media (max-width: 860px) {
  .container {
    overflow: visible;
    }
  .main-content {
    float: none;
    width: 100%;
    margin-bottom: 30px;
    padding-bottom: 0;
    }
  aside {
    float: none;
    width: 100%;
    margin-bottom: 0;
    padding-bottom: 0;
    }
  .main-content div, aside  div {
    padding: 30px;
}
  footer {
    margin-top: 0;
  }
}

3. По типу таблицы

В данном примере используется особенность html-таблиц, благодаря которой все ячейки одного ряда принимают одинаковую высоту, равную высоте самой высокой ячейки.

<header>Шапка страницы</header>
  <div class="container">
    <div class="main-content">
      <div class="content-wrap">
        <h1>Основной контент</h1>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
      </div>
      <aside>
        <h2>Боковая колонка</h2>
        <p>Nullam ac imperdiet mi. In efficitur iaculis erat id mattis...</p>
      </aside>
    </div>
  </div>
<footer>Подвал страницы</footer>
body {
  margin: 0;
  background: #FAF2D6;
  color: #302E2D;
}
header {
  padding: 30px 60px;
  background: #80C8A0;
  margin-bottom: 30px;
}
.container {
  display: table;
  border-collapse: separate;
  border-spacing: 30px 0;
}
.main-content {
  display: table-row;
}
.content-wrap { 
  background: #C9CCC8;
}
aside {
  width: 300px;
  background: #EC5A45;
}
.content-wrap, aside {  
  display: table-cell;
  padding: 30px;
}
footer {
  margin-top: 30px;
  padding: 30px 60px;
  background: #80C8A0;
}

С помощью медиазапроса сделаем все элементы блочными и установим для боковой колонки ширину 100%.

@media (max-width: 860px) {
  .container {
    padding: 0 30px;
  }
  .container, .main-content, .content-wrap, aside {
    display: block;
  }
  .content-wrap {
    margin-bottom: 30px;
  }
  aside {
    width: 100%;
    box-sizing: border-box;
  }
}

4. Flexbox

В Flexbox-модели каждый дочерний элемент выстраивается в ряд (вдоль главной оси) колонками одинаковой высоты, равной высоте блока-контейнера. Зафиксируем ширину боковой колонки с помощью flex-basis: 300px; и добавим ей значение flex-shrink: 0;, которое предотвратит сужение.

<header>Шапка страницы</header>
  <div class="container">
    <div class="main-content">
      <h1>Основной контент</h1>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
    </div>
    <aside>
      <h2>Боковая колонка</h2>
      <p>Nullam ac imperdiet mi. In efficitur iaculis erat id mattis...</p>
    </aside>
  </div>
<footer>Подвал страницы</footer>
body {
  margin: 0;
  background: #FAF2D6;
  color: #302E2D;
}
header {
  padding: 30px 60px;
  background: #80C8A0;
}
.container {
  padding: 30px;
}
.main-content {
  margin-right: 30px;
  background: #C9CCC8;
  padding: 30px;
}
aside {
  background: #EC5A45;
  padding: 30px;
  flex-basis: 300px;
  flex-shrink: 0;
}
footer {
  padding: 30px 60px;
  background: #80C8A0;
}

Укажем медиазапрос, в котором флекс-модель будет применяться к элементам для ширины области просмотра от 860px.

@media (min-width: 860px) {
  .container {
    display: flex;
  }
}
@media (max-width: 859px) {
  .main-content {
    margin: 0 0 30px 0;
  }
}

5. Плагин matchHeight

Самый простой способ, который будет работать во всех современных браузерах и IE8+. Скачать плагин можно со страницы разработчика. Эта библиотека позволяет устанавливать одинаковую высоту как в одном ряду, так и во всех рядах одновременно. Для всех колонок задаём одинаковый класс (в данном примере item), который будет использоваться при активации плагина:

jQuery(document).ready(function($) {
  $('.item').matchHeight();
});
<header>Шапка страницы</header>
  <div class="container">
    <div class="item main">
      <h1>Основной контент</h1>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
    </div>
    <aside class="item">
      <h2>Боковая колонка</h2>
      <p>Nullam ac imperdiet mi. In efficitur iaculis erat id mattis...</p>
    </aside>
  </div>
<footer>Подвал страницы</footer>
*{box-sizing:border-box}
body {
  margin: 0;
  background: #FAF2D6;
  color: #302E2D;
}
header {
  padding: 30px 60px;
  background: #80C8A0;
}
.container {
  padding: 30px;
}
.container:after {
  content:"";
  display: table;
  clear: both;
}
.item {
  background: #EC5A45;
  padding: 30px;
}
.main {
  float: left;
  width: calc(100% - 330px);
}
aside {
  width: 300px;
  float: right;
}
footer {
  padding: 30px 60px;
  background: #80C8A0;
}

С помощью медиазапроса отменим обтекание колонок и укажем определение высоты колонок в зависимости от высоты их содержимого.

@media (max-width: 860px) {
  .item {
    height: auto !important;
    float: none;
    width: 100%;
  } 
  .main {
    margin-bottom: 30px;
  }
}

6. jQuery функция css()

В данном примере определяется высота каждой колонки и проверяется условие, в результате чего колонки принимают одинаковую (наибольшую) высоту.

<header>Шапка страницы</header>
<div class="container">
  <div class="main">
    <h1>Основной контент</h1>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
  </div>
  <aside>
    <h2>Боковая колонка</h2>
    <p>Nullam ac imperdiet mi. In efficitur iaculis erat id mattis...</p>
  </aside>
</div>
<footer>Подвал страницы</footer>
*{box-sizing:border-box}
body {
  margin: 0;
  background: #FAF2D6;
  color: #302E2D;
}
header {
  padding: 30px 60px;
  background: #80C8A0;
}
.container {
  padding: 30px;
}
.container:after {
  content:"";
  display: table;
  clear: both;
}
.main {
  float: left;
  width: calc(100% - 330px);
  background: #EC5A45;
  padding: 30px;
}
aside {
  width: 300px;
  float: right;
  background: #EC5A45; 
  padding: 30px;
}
footer {
  padding: 30px 60px;
  background: #80C8A0;
}

С помощью медиазапроса отменим обтекание колонок и укажем определение минимальной высоты колонок в зависимости от высоты их содержимого.

@media (max-width: 860px) {
  .main, aside {
   min-height: auto !important;
   float: none;
   width: 100%;
 } 
  .main {
   margin-bottom: 30px;
 }
}
jQuery(document).ready(function($) {
  var content = $('.main');
  var sidebar = $('aside');
  var getContentHeight = content.outerHeight();
  var getSidebarHeight = sidebar.outerHeight();
  
  if (getContentHeight > getSidebarHeight) {
    sidebar.css('min-height', getContentHeight);
    }
  if (getSidebarHeight > getContentHeight) {
    content.css('min-height', getSidebarHeight);
    }
});
  • Создание Сайтов

    Это очень полезная статья. Извечная проблема колонок.

  • Evgeniy Belousov

    Полезная статья, отдельное спасибо за плагин «matchHeight». Пользовался раньше «equalheights», тоже неплохой, но у этого больше возможностей

    • Пожалуйста. Согласна, плагин matchHeight более удачный. В своё время, когда нужно было решить подобную проблему, equalheights сразу не впечатлил.

  • fgeniy

    метод jQuery самый практичный, как по мне. Спасибо

    • Пожалуйста

      • fgeniy

        но похоже, что если колонок будет больше чем 2, то возникает проблема..

        • в общем статья писалась под две колонки, поддержка большего количества есть у плагина matchHeight, остальные варианты пока не тестировала.

  • Антон Дьяков

    Достаточно родительскому диву задать display:flex и можно напихивать его дивами, все они будут одинаковы по высоте

    • В этом уроке приведены разные варианты и флексбокс, который не работает в старых браузерах, среди них тоже присутствует.