Две оси — единственное, что нужно понять
Flex-контейнер раскладывает детей вдоль главной оси и выравнивает поперёк неё. Всё остальное — следствие.
| Контейнер | Главная ось | justify-* | items-* |
|---|---|---|---|
flex | горизонталь | слева направо | по вертикали |
flex-col | вертикаль | сверху вниз | по горизонтали |
justify — «вдоль»,
items — «поперёк». Перепутали — переверните контейнер
flex-col и посмотрите, что изменилось.justify-start (по умолчанию)
justify-center
justify-between
<div class="space-y-3">
<p class="text-xs font-medium text-slate-500">justify-start (по умолчанию)</p>
<div class="flex gap-2 rounded-lg bg-slate-100 p-2">
<div class="rounded bg-sky-600 px-3 py-2 text-xs text-white">1</div>
<div class="rounded bg-sky-600 px-3 py-2 text-xs text-white">2</div>
<div class="rounded bg-sky-600 px-3 py-2 text-xs text-white">3</div>
</div>
<p class="text-xs font-medium text-slate-500">justify-center</p>
<div class="flex justify-center gap-2 rounded-lg bg-slate-100 p-2">
<div class="rounded bg-sky-600 px-3 py-2 text-xs text-white">1</div>
<div class="rounded bg-sky-600 px-3 py-2 text-xs text-white">2</div>
<div class="rounded bg-sky-600 px-3 py-2 text-xs text-white">3</div>
</div>
<p class="text-xs font-medium text-slate-500">justify-between</p>
<div class="flex justify-between gap-2 rounded-lg bg-slate-100 p-2">
<div class="rounded bg-sky-600 px-3 py-2 text-xs text-white">1</div>
<div class="rounded bg-sky-600 px-3 py-2 text-xs text-white">2</div>
<div class="rounded bg-sky-600 px-3 py-2 text-xs text-white">3</div>
</div>
</div>
Представьте полку с книгами. justify-* решает, где книги стоят
вдоль полки: слева, по центру, вплотную к краям. items-* решает,
как они выровнены по высоте: по нижнему краю, по центру, растянуты до самого
верха. Поворот полки на бок — это и есть flex-col.
Выравнивание поперёк
items-start · items-center · items-stretch
<div class="space-y-3">
<p class="text-xs font-medium text-slate-500">items-start · items-center · items-stretch</p>
<div class="flex h-24 items-start gap-2 rounded-lg bg-slate-100 p-2">
<div class="rounded bg-emerald-600 px-3 py-2 text-xs text-white">start</div>
<div class="rounded bg-emerald-600 px-3 py-4 text-xs text-white">выше</div>
</div>
<div class="flex h-24 items-center gap-2 rounded-lg bg-slate-100 p-2">
<div class="rounded bg-emerald-600 px-3 py-2 text-xs text-white">center</div>
<div class="rounded bg-emerald-600 px-3 py-4 text-xs text-white">выше</div>
</div>
<div class="flex h-24 items-stretch gap-2 rounded-lg bg-slate-100 p-2">
<div class="rounded bg-emerald-600 px-3 py-2 text-xs text-white">stretch</div>
<div class="rounded bg-emerald-600 px-3 py-2 text-xs text-white">оба на всю высоту</div>
</div>
</div>
Рост и сжатие: flex-1, shrink-0, basis
Три класса решают почти все задачи распределения места:
flex-1— «занять всё свободное место», можно нескольким элементам сразу — они поделят место поровну;shrink-0— «не сжимайся», обязателен для иконок и аватаров;basis-*— стартовый размер до распределения остатка.
<div class="flex gap-2 rounded-lg bg-slate-100 p-2">
<div class="shrink-0 rounded bg-slate-700 px-3 py-2 text-xs text-white">shrink-0</div>
<div class="flex-1 rounded bg-violet-600 px-3 py-2 text-xs text-white">flex-1 — забирает остаток</div>
<div class="shrink-0 rounded bg-slate-700 px-3 py-2 text-xs text-white">shrink-0</div>
</div>
Почему не w-full? Потому что w-full — это «100%
родителя», и во flex-строке такой элемент выдавит соседей. flex-1
считает именно оставшееся место.
min-w-0: почему текст «распирает» строку
По умолчанию flex-элемент не может стать меньше своего содержимого
(min-width: auto). Длинное слово или ссылка «распирают» строку,
и truncate не срабатывает. Лечение — min-w-0:
Без min-w-0: оченьдлинноеназваниефайлакотороенепомещается.pdf
С min-w-0: оченьдлинноеназваниефайлакотороенепомещается.pdf
<div class="space-y-3">
<div class="flex max-w-sm gap-3 rounded-lg border border-slate-200 p-3">
<div class="size-9 shrink-0 rounded-full bg-rose-200"></div>
<p class="truncate text-sm text-slate-700">Без min-w-0: оченьдлинноеназваниефайлакотороенепомещается.pdf</p>
</div>
<div class="flex max-w-sm gap-3 rounded-lg border border-slate-200 p-3">
<div class="size-9 shrink-0 rounded-full bg-emerald-200"></div>
<p class="min-w-0 truncate text-sm text-slate-700">С min-w-0: оченьдлинноеназваниефайлакотороенепомещается.pdf</p>
</div>
</div>
Перенос строк
flex-wrap разрешает элементам переходить на следующую строку.
Это простейший способ сделать раскладку адаптивной без медиазапросов:
<div class="flex flex-wrap gap-2">
<span class="rounded-full bg-slate-200 px-3 py-1 text-xs text-slate-700">дизайн</span>
<span class="rounded-full bg-slate-200 px-3 py-1 text-xs text-slate-700">вёрстка</span>
<span class="rounded-full bg-slate-200 px-3 py-1 text-xs text-slate-700">типографика</span>
<span class="rounded-full bg-slate-200 px-3 py-1 text-xs text-slate-700">доступность</span>
<span class="rounded-full bg-slate-200 px-3 py-1 text-xs text-slate-700">адаптивность</span>
<span class="rounded-full bg-slate-200 px-3 py-1 text-xs text-slate-700">анимация</span>
</div>
Центрирование двумя классами
Классическая задача «центрировать по вертикали и горизонтали» решается так:
<div class="flex h-32 items-center justify-center rounded-lg border border-dashed border-slate-300">
<span class="rounded-md bg-slate-900 px-4 py-2 text-sm text-white">flex items-center justify-center</span>
</div>
Когда flex, а когда grid
| Задача | Инструмент |
|---|---|
| Ряд элементов, размеры зависят от содержимого | Flexbox |
| Шапка: слева логотип, справа кнопки | Flexbox |
| Сетка карточек с равными колонками | Grid |
| Раскладка страницы: сайдбар + контент | Grid |
| Выравнивание пары «иконка + текст» | Flexbox |
Коротко: flex — про одну ось, grid — про две. Подробное сравнение будет в уроке 09.