Flexbox — рабочая раскладка современного веба: панели, меню, карточки, формы, «прижать кнопку вправо», «выровнять по центру» — всё это он. Модель одномерная: контейнер раскладывает детей вдоль одной оси и умеет гибко распределять между ними место. Ключ к пониманию — оси и три свойства гибкости.
Контейнер, оси и направление
display: flex на контейнере включает раскладку для его прямых детей:
.toolbar { display: flex; }
Дети встают в ряд вдоль главной оси (main axis); перпендикулярна ей поперечная (cross axis). Куда смотрит главная ось, задаёт flex-direction: row (умолчание, слева направо), column (сверху вниз), плюс реверсы. Все дальнейшие свойства привязаны к осям, а не к сторонам экрана — поменяли direction, и «горизонтальное» выравнивание стало вертикальным. Это не причуда, а сила: одна и та же логика раскладывает и строку тулбара, и колонку сайдбара.
По умолчанию дети не переносятся и могут ужиматься; flex-wrap: wrap разрешает перенос на новые линии — так строят «резиновые» галереи тегов и карточек.
Выравнивание: justify против align
Пара, которую путают всегда, различается осью:
justify-content— распределение вдоль главной оси:flex-start,center,flex-end,space-between(крайние к краям, остальное поровну между),space-around,space-evenly.align-items— выравнивание по поперечной оси:stretch(умолчание — растянуть по высоте ряда),center,flex-start,flex-end,baseline(по базовой линии текста — для строк с разным размером шрифта).
.header {
display: flex;
justify-content: space-between; /* лого влево, меню вправо */
align-items: center; /* всё по вертикальному центру */
}
Идеальное центрирование, над которым веб бился десятилетие, — три строки: display: flex; justify-content: center; align-items: center.
Точечные инструменты: align-self переопределяет align-items для одного ребёнка; margin-left: auto у ребёнка съедает всё свободное место слева — идиома «прижать последний элемент к противоположному краю» без обёрток. order меняет визуальный порядок без правки разметки (осторожно: порядок таба и скринридера остаётся по DOM — расхождение бьёт по доступности).
Отступы между детьми — свойство gap: честные промежутки только между элементами, без margin-хаков и «съедания» крайних отступов. C flex-wrap задаёт и межстрочные интервалы.
Гибкость: grow, shrink, basis
Сердце flexbox — как дети делят место. У каждого ребёнка тройка свойств:
flex-basis— стартовый размер вдоль главной оси (до распределения);auto— от содержимого.flex-grow— доля свободного места, которую ребёнок забирает (0 — не растёт).flex-shrink— готовность ужиматься при нехватке места (1 по умолчанию — ужимаются все).
Пишут их шорткатом flex: grow shrink basis. Три пресета покрывают 95 % задач:
.item-a { flex: none; } /* 0 0 auto — жёсткий: по контенту, не растёт, не жмётся */
.item-b { flex: auto; } /* 1 1 auto — от контента, добор места пропорционально */
.item-c { flex: 1; } /* 1 1 0 — РАВНЫЕ колонки: стартуем с нуля, делим всё */
Разница flex: auto и flex: 1 — в basis: auto делит только свободное место (кто был больше контентом, тот и останется больше), а flex: 1 обнуляет стартовые размеры и делит всё — колонки получаются строго равными. Классика — «инпут занимает всё, кнопка по размеру»:
.search { display: flex; gap: 8px; }
.search input { flex: 1; }
.search button { flex: none; }
Переполнение и min-width: 0
Самые известные flexbox-грабли. Внутри flex: 1-колонки лежит длинная строка без пробелов (URL, код) — и колонка отказывается ужиматься, ломая раскладку. Причина: у flex-детей min-width: auto — «не уже своего контента». Лечение — разрешить ужиматься:
.column { flex: 1; min-width: 0; }
.column .title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
Без min-width: 0 не работает и обрезание текста многоточием внутри flex-колонок — теперь вы знаете, почему.
Коротко
- Flex — одномерная раскладка: главная ось (direction) и поперечная. Все свойства привязаны к осям, не к сторонам экрана.
- justify-content — вдоль главной оси, align-items — поперёк. Центрирование чего угодно — три строки.
- Тройка гибкости: basis (старт), grow (доля свободного), shrink (ужимаемость).
flex: 1— равные колонки,flex: none— жёсткий элемент,flex: auto— от контента с добором. - gap вместо margin-хаков;
margin-left: auto— прижать элемент к краю; order меняет только визуальный порядок (доступность!). - Не ужимается / не работает ellipsis — ставьте
min-width: 0flex-ребёнку.
Что почитать дальше
- Grid — двумерная раскладка: когда рядов и колонок много и они связаны.
- Позиционирование — предыдущая тема цикла.
- Блочная модель — почему во flex-контейнере не схлопываются margin.