Flexbox
Зачем это нужно
Поставить элементы в ряд, разнести по краям, выровнять по центру по вертикали — раньше это были
мучения с float и таблицами. Flexbox («гибкие коробки») решает такие задачи парой строк.
Шапка сайта, ряд карточек, кнопки в строку, центрирование чего угодно — всё это flex.
Контейнер и элементы
Flexbox включается у родителя:
<style>
.row { display: flex; }
.row div { padding: 20px; background: gold; }
</style>
<div class="row">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
Результат: три жёлтых блока в ряд, хотя div обычно встают друг под другом.
.row— flex-контейнер;- его прямые дети — flex-элементы. Внуки на flex не реагируют.
Две оси
У контейнера есть главная ось — вдоль неё идут элементы — и поперечная под прямым углом.
.row { flex-direction: row; } /* главная ось → слева направо (по умолчанию) */
.col { flex-direction: column; } /* главная ось ↓ сверху вниз */
Это важно: свойства выравнивания работают относительно осей, а не «по горизонтали»:
justify-content— вдоль главной оси;align-items— вдоль поперечной.
justify-content: по главной оси
.row { display: flex; justify-content: space-between; }
| Значение | Что делает |
|---|---|
flex-start |
всё в начале (по умолчанию) |
flex-end |
всё в конце |
center |
по центру |
space-between |
первый у начала, последний у конца, остальное поровну между |
space-around |
одинаковое место вокруг каждого |
space-evenly |
все промежутки одинаковые, включая края |
Результат с space-between: блок 1 у левого края, блок 3 у правого, блок 2 посередине.
align-items: по поперечной оси
.row { display: flex; align-items: center; height: 200px; }
| Значение | Что делает |
|---|---|
stretch |
растянуть на всю высоту (по умолчанию) |
flex-start / flex-end |
прижать к началу / к концу |
center |
по центру |
Результат: блоки стоят посередине по высоте 200-пиксельного контейнера.
Идеальное центрирование — то, чего долго не хватало вебу:
.screen {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
Результат: содержимое ровно в центре экрана и по горизонтали, и по вертикали.
gap: промежутки
.row { display: flex; gap: 16px; }
Результат: между элементами по 16px — но не по краям. Раньше для этого ставили margin каждому
элементу и потом убирали у последнего; gap проще.
flex-wrap: перенос
По умолчанию flex-элементы ужимаются, лишь бы влезть в одну строку. Чтобы они переносились:
.cards { display: flex; flex-wrap: wrap; gap: 10px; }
.cards div { width: 200px; }
Результат: карточки по 200px в ряд; не влезающие уходят на следующую строку. На узком экране получится одна колонка, на широком — четыре.
Свойства элементов: flex-grow, flex-shrink, flex-basis
Эти свойства задаются детям:
flex-basis— «желаемый» размер вдоль главной оси;flex-grow— какую долю свободного места забрать (0 — не расти);flex-shrink— можно ли сжиматься, если места мало (0 — нельзя).
.sidebar { flex: 0 0 250px; } /* не расти, не сжиматься, 250px */
.main { flex: 1; } /* забрать всё свободное место */
Результат: боковая колонка ровно 250px, а основная часть растягивается на всю оставшуюся ширину.
Сокращение flex: grow shrink basis. Если у двух элементов flex: 1 и flex: 2, второй получит
вдвое больше свободного места.
Отдельному элементу можно задать своё выравнивание поперёк: align-self: flex-end;.
А margin-left: auto у элемента «отталкивает» его к правому краю.
Как это работает внутри
Браузер сначала ставит элементы по их flex-basis (или ширине содержимого), потом считает,
сколько места осталось. Если место есть — делит его по flex-grow; если не хватает —
отнимает по flex-shrink. Затем раскладывает элементы вдоль главной оси по justify-content
и выравнивает поперёк по align-items.
Частые ошибки
display: flexу элементов, а не у контейнера. Flex включается у родителя.- Ждут, что сработает на внуков. Flex действует только на прямых детей. Вложенный ряд — ещё один flex-контейнер.
- Путают оси. С
flex-direction: columnjustify-contentработает по вертикали, аalign-items— по горизонтали. align-items: center«не работает». У контейнера нет высоты больше содержимого — центрировать не в чем.- Карточки сплющились. Без
flex-wrap: wrapэлементы сжимаются в одну строку.
Шпаргалка
| Свойство (у кого) | Что делает |
|---|---|
display: flex (родитель) |
включить flexbox |
flex-direction: row / column |
направление главной оси |
justify-content |
выравнивание по главной оси |
align-items |
выравнивание по поперечной оси |
gap: 16px |
промежутки между элементами |
flex-wrap: wrap |
переносить на новую строку |
flex: 1 (ребёнок) |
забрать свободное место |
flex: 0 0 200px (ребёнок) |
фиксированный размер |
align-self (ребёнок) |
своё выравнивание поперёк |