Flexbox и Grid: ключевые отличия и выбор подхода
Flexbox и Grid, чем отличаются друг от друга?
Теория: что решает Flexbox
Flexbox (Flexible Box Layout) — это режим CSS-раскладки, который упрощает выравнивание элементов и распределение свободного пространства внутри контейнера.
Внутри flex-контейнера элементы могут располагаться по строке или по колонке (в зависимости от направления), растягиваться/сжиматься под доступное место, а при включённом переносе переходить на новые линии.
Ключевая идея Flexbox — две оси:
- Основная ось (main axis): направление, вдоль которого элементы раскладываются в первую очередь.
- Поперечная ось (cross axis): направление, по которому выполняется выравнивание относительно основной оси.
Часто используемые свойства контейнера:
display: flex— включает Flexbox.flex-direction— задаёт направление:row,columnи варианты с-reverse.justify-content— распределяет элементы вдоль основной оси.align-items— выравнивает элементы по поперечной оси.flex-wrap— разрешает перенос элементов на новые линии.
Пример: панель действий, где последняя кнопка прижата к правому краю
HTML
<div class="toolbar">
<button>Назад</button>
<button>Вперёд</button>
<button class="primary">Сохранить</button>
</div>
CSS
.toolbar {
display: flex;
gap: 12px;
align-items: center;
}
.primary {
margin-left: auto;
}
Объяснение по шагам:
display: flexпревращает.toolbarв flex-контейнер, элементы внутри становятся flex-элементами.align-items: centerвыравнивает элементы по поперечной оси (обычно по вертикали, если направлениеrow).margin-left: autoзабирает всё свободное место слева от.primary, из‑за чего кнопка «уезжает» к концу строки.
order изменяет только визуальный порядок элементов, но не меняет их порядок в DOM, поэтому без необходимости не следует использовать order для смысловой перестановки важных частей интерфейса (например, пунктов навигации или полей формы).Теория: что решает Grid
Grid (Grid Layout) — это двумерная система CSS-раскладки, предназначенная для построения сеток: одновременно задаются строки и колонки, формируя структуру, в которую размещаются элементы.
Grid удобен там, где требуется «каркас» страницы, галерея, сложная сетка карточек, области макета, а также точное размещение и контроль размеров строк/колонок.
Ключевые понятия Grid:
- Сетка (grid) состоит из строк и колонок.
- Треки (tracks) — это строки и колонки.
- Линии сетки (grid lines) — границы треков; по линиям можно размещать элементы.
- Области (grid areas) — именованные прямоугольные участки сетки.
- Явная сетка (explicit grid) — заданная через
grid-template-columnsиgrid-template-rows. - Неявная сетка (implicit grid) — создаётся автоматически, когда элементов больше, чем ячеек явной сетки.
Пример: каркас страницы через области (header/sidebar/main/footer)
HTML
<div class="page">
<header class="h">Header</header>
<aside class="s">Sidebar</aside>
<main class="m">Main</main>
<footer class="f">Footer</footer>
</div>
CSS
.page {
display: grid;
grid-template-columns: 260px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"h h"
"s m"
"f f";
gap: 16px;
}
.h { grid-area: h; }
.s { grid-area: s; }
.m { grid-area: m; }
.f { grid-area: f; }
Объяснение по шагам:
display: gridвключает Grid-контекст.grid-template-columns: 260px 1frсоздаёт две колонки: фиксированную и «резиновую», которая занимает остаток ширины.grid-template-rows: auto 1fr autoсоздаёт три строки: высота по контенту, затем «резиновая», затем снова по контенту.grid-template-areasописывает карту областей; отдельные элементы «прикрепляются» к областям черезgrid-area.
Ключевые различия и выбор
Главное различие формулируется так:
- Flexbox — про раскладку элементов вдоль одной ведущей оси и удобное выравнивание/распределение пространства.
- Grid — про одновременный контроль строк и колонок, то есть про «сетку» как основу макета.
Важно понимать нюанс: у Flexbox есть перенос (flex-wrap), и визуально может получиться несколько строк, но модель по-прежнему ориентирована на поток и выравнивание по осям, а не на управление единой двумерной сеткой.
У Grid наоборот: сначала задаётся сетка, затем элементы размещаются по координатам/линиям/областям; это ближе к «планированию» макета.
Практическое правило выбора:
- Если требуется ряд/колонка элементов, выравнивание, распределение свободного места, «прижатие» одного элемента к краю — чаще подходит Flexbox.
- Если требуется макет с колонками и строками одновременно, «растянуть блок на 2 колонки», построить каркас страницы, задать области — чаще подходит Grid.
- Если требуется и то и другое — обычно используется сочетание: внешняя сетка на Grid, внутренности компонентов на Flexbox.
Таблица отличий
| Критерий | Flexbox | Grid |
|---|---|---|
| Измерения | Одна ведущая ось + выравнивание по второй; возможен перенос на линии | Две оси одновременно: строки и колонки |
| Подход | «Элементы и их размеры» определяют распределение пространства | «Сетка» задаётся явно, элементы размещаются в неё |
| Типичные задачи | Меню, панель кнопок, выравнивание в компоненте, центрирование | Каркас страницы, галерея, сложные сетки, области макета |
| Размещение | В первую очередь поток вдоль оси и выравнивание | Явное/авто размещение по линиям, областям, координатам |
| Сочетание | Часто используется внутри grid-элементов | Часто используется как внешний каркас страницы |
Схема для запоминания осей
Flexbox (выбирается ведущая ось)
[ item ][ item ][ item ] -> main axis
|
v
cross axis (выравнивание)
Grid (две оси одновременно)
columns -> | 1 | 2 | 3 |
rows v |---|---|---|
|---|---|---|
Практика: примеры и разбор
Пример 1: сетка карточек (Grid) + внутренности карточки (Flexbox)
HTML
<div class="cards">
<article class="card">
<h3>Товар</h3>
<p>Описание может быть длиннее или короче.</p>
<button>Купить</button>
</article>
<article class="card">
<h3>Товар</h3>
<p>Короткое описание.</p>
<button>Купить</button>
</article>
</div>
CSS
.cards {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.card {
display: flex;
flex-direction: column;
gap: 8px;
padding: 16px;
border: 1px solid #ddd;
}
.card button {
margin-top: auto;
}
Почему это логично:
.cards— двумерная задача (ряды и колонки карточек), поэтому Grid..card— линейная задача (содержимое сверху вниз), поэтому Flexbox.margin-top: autoприжимает кнопку к нижней части карточки, потому что свободное место «уходит» в автоматический отступ.
Пример 2: шапка сайта (Flexbox), где нужно распределить элементы по ширине
HTML
<header class="topbar">
<div class="logo">Logo</div>
<nav class="menu">
<a href="#">Главная</a>
<a href="#">Каталог</a>
<a href="#">Контакты</a>
</nav>
<div class="actions">
<button>Войти</button>
</div>
</header>
CSS
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.menu {
display: flex;
gap: 12px;
}
Почему это Flexbox:
- Требуется один ряд элементов, выравнивание по вертикали и распределение по горизонтали, то есть типичная «линейная» раскладка.
Пример 3: элемент растягивается на несколько колонок и строк (Grid)
HTML
<div class="grid">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
<div class="d">D</div>
</div>
CSS
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 120px;
gap: 12px;
}
.a {
grid-column: 1 / 4;
grid-row: 1 / 3;
}
Почему это Grid:
- Требуется точное размещение «A» по линиям сетки: занять 3 колонки и 2 строки; это сильная сторона Grid.
Итого: Flexbox предназначен для линейной раскладки и выравнивания элементов вдоль выбранной оси, Grid — для двумерной сетки со строками и колонками; на практике эти технологии часто комбинируются (каркас на Grid, компоненты на Flexbox).