Flexbox vs Grid
Flexbox — одномерная система раскладки (строка ИЛИ столбец). Grid — двумерная (строки И столбцы одновременно). Они не конкуренты, а дополняют друг друга.
Зачем нужно
Выбор между Flexbox и Grid — один из самых частых вопросов при вёрстке. Понимание сильных сторон каждого инструмента позволяет выбрать оптимальный подход и комбинировать их.
Где используется
- Flexbox: навигация, панели инструментов, карточки, центрирование, распределение элементов в ряд
- Grid: макеты страниц, карточные сетки, дашборды, формы, сложные двумерные раскладки
Предпосылки
- Основы Grid — grid-контейнер, треки, ячейки
- Блочная модель — как рассчитываются размеры
Сравнительная таблица
| Характеристика | Flexbox | Grid |
|---|---|---|
| Размерность | 1D (строка или столбец) | 2D (строки и столбцы) |
| Подход | Контент определяет раскладку | Раскладка определяет размещение |
| Оси | Главная + поперечная | inline + block |
| Wrapping | flex-wrap |
Автоматически через треки |
| Именованные области | Нет | grid-template-areas |
| Gap | gap |
gap |
| Выравнивание | justify-content, align-items |
+ justify-items, place-* |
| Перекрытие элементов | Нет (без position) | Да (элементы могут наложиться) |
| Subgrid | Нет | Да |
Когда использовать Flexbox
1. Однонаправленный поток
/* Навигация */
.nav {
display: flex;
gap: 16px;
align-items: center;
}
/* Панель кнопок */
.toolbar {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
2. Контент определяет размер
/* Теги — каждый по ширине содержимого */
.tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.tag {
padding: 4px 12px;
background: #e9ecef;
border-radius: 16px;
/* Ширина = по содержимому */
}
3. Распределение пространства
/* Sidebar + Content */
.layout {
display: flex;
}
.sidebar {
flex: 0 0 250px; /* Фиксированный */
}
.content {
flex: 1; /* Занимает всё оставшееся */
}
4. Центрирование
/* Идеальное центрирование */
.center {
display: flex;
justify-content: center;
align-items: center;
min-height: 100dvh;
}
Когда использовать Grid
1. Двумерный макет
/* Макет страницы */
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
}
2. Сетка одинаковых элементов
/* Галерея / каталог */
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
3. Элементы должны выравниваться в обоих направлениях
/* Форма */
.form {
display: grid;
grid-template-columns: max-content 1fr;
gap: 12px 16px;
align-items: center;
}
/* label и input автоматически в двух колонках */
4. Наложение элементов
/* Карточка с изображением и текстом поверх */
.hero-card {
display: grid;
}
.hero-card img,
.hero-card .overlay {
grid-area: 1 / 1; /* Оба в одной ячейке — наложение */
}
.hero-card .overlay {
align-self: end;
background: linear-gradient(transparent, rgba(0,0,0,0.8));
color: white;
padding: 20px;
}
Комбинация Flexbox + Grid
Они прекрасно работают вместе:
/* Grid для макета страницы */
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
}
/* Flex для навигации внутри header */
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
}
/* Grid для сетки карточек в content */
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
}
/* Flex внутри карточки */
.card {
display: flex;
flex-direction: column;
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: auto; /* Прижать к низу */
}
Правило выбора
Нужно ли контролировать СТРОКИ и СТОЛБЦЫ одновременно?
│
├─ Да → Grid
│ ├─ Макет страницы → grid-template-areas
│ ├─ Сетка карточек → repeat(auto-fill, minmax)
│ └─ Форма → grid с колонками
│
└─ Нет, только в ОДНОМ направлении → Flexbox
├─ Навигация → flex + gap
├─ Кнопки в ряд → flex + gap
├─ Центрирование → flex + justify/align
└─ Sidebar + Content → flex + flex:1
Простое правило: Grid — для макета, Flexbox — для компонентов. Но это не строгое правило, а отправная точка.
Частые ошибки
- Использование Grid для одномерных задач — навигация из 5 ссылок не нуждается в Grid
- Использование Flexbox для двумерной сетки —
flex-wrapне гарантирует выравнивание по колонкам:/* ПЛОХО — последний ряд может быть неровным */ .cards { display: flex; flex-wrap: wrap; } .card { width: calc(33.333% - 20px); } /* ХОРОШО */ .cards { display: grid; grid-template-columns: repeat(3, 1fr); } - Боязнь комбинировать — Grid и Flexbox отлично работают вместе
- Grid для простого центрирования — и Grid, и Flexbox подходят, оба варианта валидны
Практика
- Создать навигацию через Flexbox
- Создать ту же навигацию через Grid — сравнить
- Сделать макет страницы на Grid с Flexbox-навигацией внутри
- Реализовать карточную сетку: Grid для раскладки, Flex внутри карточек
- Попробовать наложение элементов в Grid (невозможно в Flexbox без position)
Связанные темы
- Основы Grid — grid в деталях
- Grid areas — именованные области
- Практика Grid — реальные макеты