Flexbox

August 6, 2015

Давно присматриваюсь к flexbox’у, а вчера подвернулся случай с его помощью решить небольшую задачку по выравниванию блоков.

Дано: три блока с фиксированными шапкой и подвалом, центр плавающий. Нужно, чтобы при изменении одного или нескольких центров блоки оставались одинаковой высоты.

Финальная разметка:

<div class="container">
  <article class="plate">
    <header>Some header</header>
    <div class="content">
        <p>Dynamic list</p>
      
        <ul>
          <li><a href="#">Link 1</a></li>
          <li><a href="#">Link 2</a></li>
          <li><a href="#">Link 3</a></li>
          <li><a href="#">Link 4</a></li>
        </ul>
    </div>
    <footer>Some footer</footer>
  </article>
  <article class="plate">
    <header>Some header</header>
    <div class="content">
        <p>Dynamic list</p>
      
        <ul>
          <li><a href="#">Link 1</a></li>
          <li><a href="#">Link 2</a></li>
          <li><a href="#">Link 3</a></li>
          <li><a href="#">Link 4</a></li>
          <li><a href="#">Link 5</a></li>
          <li><a href="#">Link 6</a></li>
        </ul>
    </div>
    <footer>Some footer</footer>
  </article>
  <article class="plate">
    <header>Some header</header>
    <div class="content">
        <p>Dynamic list</p>
      
        <ul>
          <li><a href="#">Link 1</a></li>
          <li><a href="#">Link 2</a></li>
          <li><a href="#">Link 3</a></li>
        </ul>
    </div>
    <footer>Some footer</footer>
  </article>
</div>

Тут всё просто, переходим к стилям:

.container {
  display: -webkit-flex;
  display: -ms-flex;
  display: flex;
}

Согласно caniuse.com такого набора правил достаточно, чтобы поддержать все основные современные браузеры на десктопах и на мобильных устройствах. В пролете остаются IE версии 9 и ниже.

Далее сами колонки (у меня они почему-то плитками называются). Самое быстрое решение (и без полифилов) было назначить им выравнивание по верхней координате в случае, если flex не сработает. Получилось так:

.plate {
  ...
  display: inline-block
  vertical-align: top
  ...
}

Далее пошло все менее красиво, ибо центральной части я назначаю нижний внутренний отступ равный высоте подвала. У меня не было задачи делать его динамическим, поэтому такой вариант меня вполне устроил. Высоту подвала я не фиксирую, просто полагаюсь на отступ. Сам подвал расположен абсолютно и прибит к нижней части блока.

.plate .content {
  padding-bottom: 20px;
}
.plate footer {
  position: absolute;
  bottom: 0;
  width: 100%;
}

Ну и собственно само демо:

JS Bin on jsbin.com