Работа с flexbox

Одним из основных преимуществ использования CSS flex является то, что оно предоставляет более эффективный способ отображения макета, выравнивания контента и распределения пространства между различными контейнерами внутри основного. Flexbox определяет для дочерних элементов гибкость относительно высоты и ширины контейнера, в результате чего они могут эффективно адаптироваться внутри блока контейнера. Это делает адаптивный макет более управляемым.

Как использовать Flexbox

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

<div class="container">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

Для этого необходимо определить родительский контейнер как display flex CSS:

.container
{
  display: flex;
}

Затем нужно установить размер дочерних элементов и с помощью margin: auto задать их равномерное распределение в пределах родительского контейнера:

.box
{
  width: 200px;
  height: 200px;
  margin: auto;
}

Посмотреть демо

Свойства родительского элемента flexbox

Теперь мы рассмотрим свойства, которые можно использовать с flexbox для отображения различных вариантов дизайна страницы в зависимости от используемого типа устройств.

Свойства контейнера flexbox

Display

Свойство display позволяет определить div в качестве контейнера:

.container
{
  display: flex;
}

Flex-direction

CSS flex direction позволяет определить направление, в котором дочерние элементы будут распространяться (четыре значения):

.container
{
  display: flex;
  flex-direction: row;
}
  • row — слева направо;
  • row-reverse — справа налево;
  • column — сверху вниз;
  • column-reverse — снизу вверх.

Посмотреть пример слева направо
Посмотреть пример справа налево
Посмотреть пример сверху вниз
Посмотреть пример снизу вверх

flex-wrap

По умолчанию flexbox располагает дочерние элементы в одну строку. Но, изменив значение flex-wrap, можно разрешить их перенос на следующую строку:

.container
{
  display: flex;
  flex-wrap: nowrap;
}
  • nowrap — одна строка, слева направо;
  • wrap — несколько строк, слева направо;
  • wrap-reverse — несколько строк, справа налево.

Посмотреть пример несколько строк слева направо
Посмотреть пример несколько строк справа налево

flex-flow

Flex-flow позволяет объединить два описанных выше свойства в одно. Это сокращенное свойство, определяющее flex-direction и flex-wrap:

.container
{
  display: flex;
  flex-flow: row nowrap;
}

justify-content

Определяет, как размещаются внутри div контейнера дочерние элементы. Доступно пять различных значений этого свойства CSS flex:

  • flex-start — выравнивает элементы по началу контейнера;
  • flex-end — выравнивает элементы по концу контейнера;
  • center — выравнивает элементы по центру;
  • space-between — элементы размещаются с одинаковыми отступами друг от друга, первый элемент выравнивается по началу контейнера, последний элемент — по концу контейнера;
  • space-around — для элементов задаются одинаковые отступы со всех сторон.

Пример flex-start
Пример flex-end
Пример center
Пример space-between
Пример space-around

align-items

Align-items позволяет выровнять элементы по вертикальной оси. Доступно пять различных значений этого свойства CSS flex:

  • flex-start — выравнивает элементы по верху;
  • flex-end — выравнивает элементы по низу;
  • center — центрирует элементы по вертикали;
  • baseline — выравнивает элементы по базовому уровню;
  • stretch — растягивает элементы, чтобы они соответствовали размерам контейнера.

Пример flex-start
Пример flex-end
Пример center
Пример baseline
Пример stretch

align-content

Выравнивает контент и пространство между полями, когда контент перемещается на несколько строк. Доступно шесть значений этого свойства CSS flex 1:

  • flex-start — несколько строк будут смещены к началу контейнера;
  • flex-end — несколько строк будут смещены к концу контейнера;
  • center — несколько строк будут размещены по центру;
  • space-between — для нескольких строк будет задано одинаковое расстояние между ними;
  • space-around — для нескольких строк будет задано одинаковое расстояние вокруг них;
  • stretch — несколько строк будут растягиваться, чтобы занять все пространство.

Свойства дочерних элементов flexbox

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

order

По умолчанию дочерние элементы размещаются в том же порядке, в котором они размещаются в DOM. Но с помощью свойства order можно изменить порядок блоков:

.box:nth-child(1)
{
  order:2;
}

.box:nth-child(2)
{
  order:3;
}

.box:nth-child(1)
{
  order:1;
}

Посмотреть пример

flex-grow

По умолчанию все элементы в CSS flex будут принимать одинаковые размеры по ширине. Но с помощью свойства flex-grow можно сделать так, чтобы отдельные элементы растягивались в несколько раз больше, чем остальные.

Например, если для всех элементов задано значение flex-grow 1, а для одного элемента — 2, то он будет в два раза шире других элементов:

.box
{
  background: red;
  color: white;
  font-size: 60px;
  text-align: center;
  line-height: 200px;

  width: 200px;
  height: 200px;
  margin: auto 10px;

  flex-grow:1;
}

.box:nth-child(1)
{
  flex-grow:3;
}

Посмотреть пример

flex-shrink

Flex-shrink определяет, каким образом элементы будут сжиматься.

Реальные примеры

Применяя описанные выше свойства flexbox в различных комбинациях, можно создавать разнообразные шаблоны. Рассмотрим примеры использования Flexbox.

Меню навигации

Основное преимущество CSS flex заключается в том, что элементы могут адаптироваться. Когда размеры экрана изменяются, flexbox изменяет ширину блоков, чтобы они соответствовали родительскому контейнеру. Данная технология использует процентное значение размеров по отношению к родительскому контейнеру, что и позволяет элементам навигации легко адаптироваться к размеру экрана.

Очень просто перейти к размерам на всю ширину экрана устройства, изменив способ, с помощью которого flexbox реагирует на изменения.

Посмотреть демо

Посмотрите, как в приведенном выше примере элементы реагируют на различные размеры экрана. Ниже приведен код HTML и CSS, с помощью которых можно создать адаптивное меню навигации с использованием flexbox:

<nav class="site-navigation">
  <ul>
    <li><a href="">Home</a></li>
    <li><a href="">Services</a></li>
    <li><a href="">Products</a></li>
    <li><a href="">About</a></li>
    <li><a href="">Contact</a></li>
  </ul>
</nav>
.site-navigation ul {
  background: #eee;
  list-style: none;
  margin: 0;
  padding: 0;

  /**
   * Flexbox properties
   */
  display: flex;
  justify-content: space-around;
}
.site-navigation a {
  color: #333;
  display: block;
  text-decoration: none;
  text-align: center;
  padding: 1rem;
}

.site-navigation a:hover {
  background: #d4d4d4;
}

@media all and (max-width: 600px) {
  .site-navigation ul {
    /**
     * Full width navigation items
     */
    flex-flow: column wrap;
    padding: 0;
  }
}

Столбцы одинаковой высоты

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

Посмотрите, как можно создать столбцы одинаковой высоты с помощью CSS flex 1.

Посмотреть пример

Код HTML и CSS, с помощью которых можно создать такой макет:

<div class="column-container">
  <div class="column">
    <p></p>

  <p></p>
  </div>

  <div class="column">
      <p></p>
  </div>

  <div class="column">
      <p></p>
  </div>
</div>
.column-container {
  display: flex;
  align-items: stretch;
}

.column {
  width: 33%;
  padding: 2rem;
}

.column:nth-child(1) {
  background: red;
}

.column:nth-child(2) {
  background: blue;
}

.column:nth-child(3) {
  background: green;
}

В этом коде CSS единственным свойством, которое нужно задать для получения одинаковых столбцов, является align-items: stretch:

.column-container {
  display: flex;
  align-items: stretch;
}

Центрирование по вертикали

Получить элемент, выровненный вертикально по центру внутри родительского элемента, ранее было непростой задачей. Это проще было сделать с помощью переходов и абсолютного позиционирования:

.vertically-align-center-child
{
    top: 50%; 
    transform: translateY(-50%);
}

Но с помощью flexbox это делается еще проще. Для этого используются два свойства CSS flex1:justify-content и align-items.

Посмотреть пример

<div class="vertical-container">
  <div class="vertical-content">Look I'm Vertically Aligned</div>
</div>
.vertical-container
{
  background:#eee;
  height: 500px;

  /** make it flex */
  display: flex;
  /** Vertically center */
  align-items: center;
  /** Horizontally center */
  justify-content: center;
}
.vertical-content
{
  background: #FFF;
  padding: 3rem;
  width: 20%;

  text-align: center;
}

Изменение порядка вывода элементов с помощью медиа-запросов

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

С помощью display flex CSS мы можем изменить порядок вывода различных разделов. Можно переместить блок основного контента перед левым сайдбаром.

Чтобы изменить порядок вывода дочерних элементов, нужно добавить для элемента свойство order и указать, на какой позиции он должен отображаться:

@media only screen and (max-width: 320px) 
{
  .site-header
  {
    order: 2;
  }
  .main-content
  {
    order: 1;
    width: 100%;
  }
  .left-sidebar
  {
    order: 4;
    width: 100%;
  }
  .right-sidebar
  {
    order: 3;
    width: 100%;
  }
  .site-footer
  {
    order: 5;
  }
}

Теперь порядок размещения будет следующим:

  • Основной контент;
  • Заголовок;
  • Правая боковая панель;
  • Левая боковая панель;
  • Подвал.

Просмотрите приведенную ниже демо-версию. Измените размеры окна браузера, чтобы увидеть, как меняются местами области страницы.

Посмотреть демо-версию

Поддержка браузерами

Сейчас flexbox поддерживается в 88% браузеров:

  • Chrome 21+ поддерживает flexbox без префикса;
  • Firefox 22+ поддерживает flexbox без префикса;
  • Safari поддерживает flexbox с префиксом – webkit;
  • Opera 12.1+ поддерживает flexbox без префикса;
  • IE 10 поддерживает flexbox с префиксом -MS, но уже IE11 поддерживает flexbox без префикса.

Баги flexbox

На Github существует проект со списком ошибок CSS flex и способами, как их можно обойти, пока проблема не будет устранена в движках браузеров.

Перевод статьи «How To Get Started With CSS Flexbox» был подготовлен дружной командой проекта Сайтостроение от А до Я.