Урок 8. Flexbox — блоки в ряд и по центру
Блочные элементы по умолчанию встают друг под другом. Чтобы поставить их в ряд, раздвинуть по краям или выровнять по центру, есть Flexbox — способ раскладки, который включается одной строкой и работает во всех современных браузерах.
Контейнер и элементы
Flexbox задаётся родителю — контейнеру. Его прямые дети становятся флекс-элементами и выстраиваются в ряд:
<div class="row">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>.row {
display: flex;
gap: 16px;
}
.box {
padding: 20px;
background-color: lightblue;
}Три блока встали в строку, между ними — 16 пикселей (gap). Действует это только на прямых детей: элементы внутри .box живут по своим правилам.
Две оси
У флекс-контейнера есть главная ось — вдоль неё выстраиваются элементы — и поперечная, под прямым углом к ней. Направление главной оси задаёт flex-direction:
row(по умолчанию) — слева направо, в строку;column— сверху вниз, в колонку;row-reverseиcolumn-reverse— в обратном порядке.
Это важно для двух главных свойств выравнивания: justify-content работает вдоль главной оси, align-items — вдоль поперечной. При flex-direction: column они меняются ролями: justify-content двигает элементы по вертикали.
Выравнивание вдоль главной оси
justify-content распределяет элементы и свободное место между ними:
| Значение | Что делает |
|---|---|
flex-start | прижимает к началу (по умолчанию) |
flex-end | прижимает к концу |
center | собирает по центру |
space-between | крайние — к краям, остальные — с равными промежутками |
space-around | равные поля вокруг каждого элемента |
space-evenly | равные промежутки везде, включая края |
Выравнивание поперёк
align-items выравнивает элементы по поперечной оси (в строке — по вертикали):
stretch(по умолчанию) — растягивает элементы на всю высоту контейнера; поэтому колонки в ряд получаются одинаковой высоты;center— по центру;flex-startиflex-end— к верху и к низу;baseline— по линии текста.
Отдельному элементу выравнивание можно поменять свойством align-self.
Центр по горизонтали и вертикали
Самая известная задача, которую Flexbox решает в три строки:
.center {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
}Всё, что внутри .center, окажется точно посередине. Высота контейнеру нужна: у блока без неё высота равна содержимому, и по вертикали двигать некуда.
Перенос на новую строку
По умолчанию все элементы встают в одну строку и сжимаются, если не помещаются. flex-wrap: wrap разрешает переносить их на следующую строку:
.cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
flex: 1 1 250px;
}Каждая карточка начинается с ширины 250 пикселей, может расти и сжиматься. В ряд встаёт столько карточек, сколько поместится, а оставшееся место делится между ними поровну. На телефоне карточки встанут по одной.
Обратная сторона: если в последнем ряду карточка одна, она растянется на всю ширину. Когда нужна ровная сетка одинаковых ячеек, удобнее Grid — о нём следующий урок.
Сколько места берёт элемент
Свойство flex у элемента — это три числа сразу:
flex-grow— какую долю свободного места забрать (0 — не расти);flex-shrink— можно ли сжиматься, если места не хватает (0 — нельзя);flex-basis— начальный размер до раздела места.
Часто нужны три записи:
.sidebar {
flex: 0 0 250px;
}
.content {
flex: 1;
}flex: 0 0 250px — ровно 250 пикселей, не больше и не меньше. flex: 1 — забрать всё оставшееся место. Если у двух элементов flex: 1, место делится поровну, если у одного flex: 2 — ему вдвое больше.
Пример: шапка сайта
Логотип слева, меню справа:
<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>.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 у элемента забирает всё свободное место слева от него и отодвигает его (и всех, кто после него) вправо.
Частые ошибки
- Свойства не действуют —
justify-contentиalign-itemsнаписаны у элементов, а не у контейнера. Они пишутся тому, у когоdisplay: flex. align-items: centerничего не меняет — у контейнера нет высоты больше содержимого.- Длинное слово или ссылка вылезает за блок — флекс-элемент по умолчанию не сжимается меньше своего содержимого. Задайте ему
min-width: 0. - Отступы между элементами через margin с «лишним» отступом у последнего — используйте
gap: он ставит промежутки только между элементами.
Коротко
display: flexу родителя ставит прямых детей в ряд;flex-direction: column— в колонку.justify-content— вдоль главной оси,align-items— поперёк.- Центр по обеим осям:
display: flex; justify-content: center; align-items: center;и высота у контейнера. gap— промежутки между элементами,flex-wrap: wrap— перенос на новую строку.flex: 1— занять оставшееся место,flex: 0 0 250px— фиксированный размер.