Глиф Учебники

Урок 8. Flexbox — блоки в ряд и по центру

Курс «HTML и CSS» · урок 8 из 10 · 4 минуты чтения

Блочные элементы по умолчанию встают друг под другом. Чтобы поставить их в ряд, раздвинуть по краям или выровнять по центру, есть Flexbox — способ раскладки, который включается одной строкой и работает во всех современных браузерах.

Контейнер и элементы

Flexbox задаётся родителю — контейнеру. Его прямые дети становятся флекс-элементами и выстраиваются в ряд:

HTML
<div class="row">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
</div>
CSS
.row {
  display: flex;
  gap: 16px;
}
.box {
  padding: 20px;
  background-color: lightblue;
}

Три блока встали в строку, между ними — 16 пикселей (gap). Действует это только на прямых детей: элементы внутри .box живут по своим правилам.

Две оси

У флекс-контейнера есть главная ось — вдоль неё выстраиваются элементы — и поперечная, под прямым углом к ней. Направление главной оси задаёт flex-direction:

Это важно для двух главных свойств выравнивания: justify-content работает вдоль главной оси, align-items — вдоль поперечной. При flex-direction: column они меняются ролями: justify-content двигает элементы по вертикали.

flex-direction: row по умолчанию 1 2 3 главная поперечная главная ось: justify-content поперечная ось: align-items flex-direction: column 1 2 3 главная поперечная
При flex-direction: row главная ось идёт слева направо, а поперечная — сверху вниз, при column — наоборот; justify-content всегда работает вдоль главной оси, align-items — вдоль поперечной.

Выравнивание вдоль главной оси

justify-content распределяет элементы и свободное место между ними:

ЗначениеЧто делает
flex-startприжимает к началу (по умолчанию)
flex-endприжимает к концу
centerсобирает по центру
space-betweenкрайние — к краям, остальные — с равными промежутками
space-aroundравные поля вокруг каждого элемента
space-evenlyравные промежутки везде, включая края
justify-content: flex-start 1 2 3 flex-end 1 2 3 center 1 2 3 space-between 1 2 3 space-around 1 2 3 space-evenly 1 2 3
Три элемента в строке при каждом значении justify-content: прижаты к началу, к концу, собраны по центру или раздвинуты с промежутками по-разному у краёв.

Выравнивание поперёк

align-items выравнивает элементы по поперечной оси (в строке — по вертикали):

Отдельному элементу выравнивание можно поменять свойством align-self.

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

Самая известная задача, которую Flexbox решает в три строки:

CSS
.center {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 300px;
}

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

Перенос на новую строку

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

CSS
.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}
.card {
  flex: 1 1 250px;
}

Каждая карточка начинается с ширины 250 пикселей, может расти и сжиматься. В ряд встаёт столько карточек, сколько поместится, а оставшееся место делится между ними поровну. На телефоне карточки встанут по одной.

Обратная сторона: если в последнем ряду карточка одна, она растянется на всю ширину. Когда нужна ровная сетка одинаковых ячеек, удобнее Grid — о нём следующий урок.

Сколько места берёт элемент

Свойство flex у элемента — это три числа сразу:

Часто нужны три записи:

CSS
.sidebar {
  flex: 0 0 250px;
}
.content {
  flex: 1;
}

flex: 0 0 250px — ровно 250 пикселей, не больше и не меньше. flex: 1 — забрать всё оставшееся место. Если у двух элементов flex: 1, место делится поровну, если у одного flex: 2 — ему вдвое больше.

контейнер 960px flex: 0 0 250px 250px flex: 1 710px — всё остальное контейнер 600px flex: 0 0 250px 250px flex: 1 350px контейнер 600px flex: 1 200px flex: 2 400px — вдвое больше
Элемент с flex: 0 0 250px остаётся шириной 250px в контейнере любой ширины, а элемент с flex: 1 забирает остаток; при flex: 1 и flex: 2 место делится в отношении один к двум.

Пример: шапка сайта

Логотип слева, меню справа:

HTML
<header class="site-header">
  <a class="logo" href="index.html">Кулинарный кружок</a>
  <nav class="menu">
    <a href="recipes.html">Рецепты</a>
    <a href="schedule.html">Расписание</a>
    <a href="contacts.html">Контакты</a>
  </nav>
</header>
CSS
.site-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 20px;
}
.menu {
  display: flex;
  gap: 20px;
}

.site-header раздвигает логотип и меню по краям, а .menu — ещё один флекс-контейнер внутри — ставит ссылки в ряд. Вложенные флекс-контейнеры — обычное дело.

Ещё один приём: margin-left: auto у элемента забирает всё свободное место слева от него и отодвигает его (и всех, кто после него) вправо.

Частые ошибки

Коротко

Проверьте себя

1. Кому пишут display: flex, чтобы три блока встали в ряд?
2. Какое свойство раздвинет элементы так, чтобы крайние прижались к краям контейнера?
3. При flex-direction: column что двигает элементы по вертикали?
4. Что означает flex: 1 у элемента?