Что такое Flexbox и чем он отличается от Grid? Когда использовать каждый?
Flexbox — одномерный лейаут (строка или колонка): навигация, карточки в строку, выравнивание элементов. Grid — двумерный (строки + столбцы): сетки карточек, лейаут страниц. Их часто комбинируют: Grid для структуры, Flexbox внутри компонентов.
Flexbox и Grid — сравнение и применение
Flexbox и CSS Grid — два самостоятельных механизма лейаута. Они не конкурируют, а дополняют друг друга, решая разные классы задач. Ключевое различие: Flexbox — одномерный (ось X или Y), Grid — двумерный (X и Y одновременно).
Flexbox — одномерный лейаут
Flexbox управляет расположением элементов вдоль одной главной оси (flex-direction: row или column). Элементы растягиваются, сжимаются и выравниваются вдоль этой оси и перпендикулярно ей (cross axis).
.nav {
display: flex;
flex-direction: row;
align-items: center; /* выровнять по вертикали */
gap: 16px;
}
/* Кнопки в строку, последняя прижата вправо */
.toolbar {
display: flex;
align-items: center;
gap: 8px;
}
.toolbar__spacer {
flex: 1; /* занимает всё свободное место */
}
/* Вертикальная колонка с равномерным распределением */
.sidebar {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
}
Когда применять Flexbox:
- Навигационные панели (горизонтальные или вертикальные меню)
- Строки форм — лейбл + поле + кнопка
- Карточки в строку с переносом через
flex-wrap - Центрирование одного элемента по обеим осям
- Группа кнопок, иконок, тегов
CSS Grid — двумерный лейаут
Grid работает сразу с двумя осями — строками и столбцами. Элементы можно явно помещать в конкретные ячейки, растягивать на несколько строк/столбцов, создавать именованные области.
/* Базовая сетка карточек */
.cards-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
/* Адаптивная сетка без media queries */
.auto-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
/* Именованные области для лейаута страницы */
.page-layout {
display: grid;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
grid-template-columns: 240px 1fr;
grid-template-rows: 64px 1fr 48px;
min-height: 100vh;
}
.page-header { grid-area: header; }
.page-sidebar { grid-area: sidebar; }
.page-content { grid-area: content; }
.page-footer { grid-area: footer; }
/* Элемент, занимающий несколько колонок */
.featured-card {
grid-column: span 2;
grid-row: span 2;
}
Когда применять Grid:
- Сетки карточек (2, 3, 4 колонки)
- Лейаут всей страницы (header/sidebar/content/footer)
- Галереи с элементами разных размеров
- Сложные формы с колонками
- Любой дизайн, требующий выравнивания по строкам И столбцам
Используем оба вместе
/* Grid для общего лейаута страницы */
.page {
display: grid;
grid-template-columns: 280px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
/* Flexbox внутри каждой карточки */
.job-card {
display: flex;
flex-direction: column;
gap: 12px;
}
.job-card__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.job-card__tags {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
Сравнительная таблица
- Оси: Flexbox — 1 (row или column); Grid — 2 (row + column)
- Управление: Flexbox — из контейнера, дети гибко заполняют место; Grid — точное размещение по ячейкам
- Задача: Flexbox — компоненты, строки UI; Grid — лейаут страниц, сетки контента
- Перенос: Flexbox —
flex-wrap(перенос, но без выравнивания по сетке); Grid —auto-fill/auto-fit(строгое выравнивание) - Совместимость: оба поддерживаются всеми современными браузерами
Подводные камни
- flex-basis vs width: в Flexbox
flex-basisимеет приоритет надwidthпри расчёте начального размера. Путаница между ними — частая причина неожиданных размеров. - flex: 1 — сокращение:
flex: 1раскрывается вflex: 1 1 0%(неflex: 1 1 auto). Разница в поведении при переполнении. - Grid: implicit tracks: если элементов больше, чем явно заданных ячеек, Grid создаёт неявные строки с
grid-auto-rows: auto. Это может сломать дизайн, если не задатьgrid-auto-rows. - gap vs margin: свойство
gapне добавляет отступ снаружи контейнера — только между элементами. Не путайте сmargin. - align-items в Grid: по умолчанию
align-items: stretch— элементы растягиваются на всю высоту ячейки. Это неожиданно для карточек с разным контентом. - Вложенный Grid не наследует треки: дочерний
display: gridсоздаёт независимую сетку, не выровненную с родительской. Для выравнивания вложенных элементов по родительской сетке используйтеsubgrid. - Flexbox и min-width: flex-элементы не сжимаются меньше своего min-content по умолчанию. Для разрешения переноса текста или сжатия нужен явный
min-width: 0. - Неправильный выбор инструмента: применять Grid там, где нужен Flexbox (и наоборот) — лишний код. Правило: одна ось — Flexbox; две оси — Grid.
Common mistakes
- Смешивать «Flexbox и Grid» с похожим механизмом без критерия выбора.
- Игнорировать риск: неверно оценить границы применения темы «Flexbox и Grid» и получить хрупкое решение.
- Показывать только синтаксис и не объяснять поведение в runtime или сборке.
What the interviewer is testing
- Объясняет выбор между одномерным распределением и двумерной сеткой.
- Показывает на примере, как работает: Flexbox раскладывает элементы вдоль главной оси и хорошо решает распределение внутри строки или колонки, а Grid задает строки и колонки как явную двумерную систему.
- Называет production-нюанс и граничный случай для темы «Flexbox и Grid».