CSS Flexbox против Grid: какую систему верстки выбрать?
И Flexbox, и CSS Grid могут давать схожие результаты, поэтому разработчики порой выбирают не тот инструмент. Разница заключается в одном измерении против двух — и понимание того, с чем вы работаете, делает выбор очевидным.
Правило одного предложения
Используйте Flexbox, когда вы располагаете элементы в одном направлении (в строку или в столбец). Используйте CSS Grid, когда вам нужно контролировать макет в двух направлениях одновременно (строки и столбцы одновременно).
Это и есть всё основное решение. Все остальное — это детализация того, почему это правило работает на практике.
Для чего на самом деле подходит Flexbox
Flexbox был разработан для распределения пространства вдоль одной оси. Его ключевая особенность заключается в том, что элементы могут расти, сжиматься и переноситься естественным образом без указания точных размеров для каждого из них.
Вот случаи, когда Flexbox является правильным выбором:
- Навигационные панели — строка ссылок, где вы хотите, чтобы определенные элементы были прижаты к правому краю (
margin-left: auto) или равномерно распределены (justify-content: space-between>) - Ряды карточек, где каждая карточка имеет одинаковую высоту независимо от длины контента (<
align-items: stretchобрабатывает это автоматически) - Центрирование элемента по горизонтали и вертикали внутри контейнера — три строки CSS: <
display: flex; justify-content: center; align-items: center> - Группы кнопок, комбинации «иконка + подпись» и любые компоненты, где дочерние элементы должны располагаться рядом с некоторым отступом
- Переносимые списки, где вы хотите, чтобы элементы переносились на следующую строку, когда место заканчивается (<
flex-wrap: wrap>)
.navbar {
display: flex;
align-items: center;
gap: 1rem;
}
.navbar .logo { margin-right: auto; }
/* logo stays left, links stay right */
Для чего на самом деле подходит CSS Grid
Grid был разработан для двухмерных макетов — вы определяете и строки, и столбцы, и можете точно размещать элементы в ячейках, охватывать несколько строк или столбцов и создавать отступы в обоих направлениях.
Вот случаи, когда Grid является правильным выбором:
- Макеты страниц — заголовок, боковая панель, основной контент, футер — всё позиционируется относительно друг друга
- Макеты журналов или дашбордов, где разные элементы занимают разное количество места
- Галереи изображений с согласованной сеткой независимо от размера изображения
- Макеты форм, где подписи и поля ввода должны быть выровнены как по горизонтали, так и по вертикали
- Любой макет, где вы думаете о строках И столбцах одновременно
.page {
display: grid;
grid-template-columns: 250px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100dvh;
}
Пример «бок о бок»: Сетка карточек
Вот здесь возникает путаница. Обе системы могут создать ряд карточек:
.card-row {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.card { flex: 1 1 280px; }
С Grid:
.card-row {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1rem;
}
Оба варианта работают. Версия с Grid обычно предпочтительнее здесь, потому что <auto-fill> с <minmax> дает более предсказуемое поведение столбцов — каждый столбец имеет точно одинаковую ширину, а сетка чисто перестраивается. Версия с Flexbox лучше подходит тогда, когда карточки могут иметь переменную ширину и вы хотите, чтобы они более гибко использовали доступное пространство.
Разница в выравнивании
В Flexbox вы выравниваете элементы вдоль основной оси (выбранного вами направления) и поперечной оси (перпендикулярно ей). Вы не можете независимо контролировать положение ячейки внутри невидимой сетки строк и столбцов.
В Grid каждый элемент находится в ячейке с позицией как по строке, так и по столбцу. Вы можете явно разместить элемент во 2-й строке, 3-м столбце или позволить браузеру разместить его автоматически. В Flexbox нет понятия ячеек — элементы просто текут в указанном вами направлении.
Распространенные ошибки
Использование Grid для простого центрирования: <display: flex; align-items: center; justify-content: center> работает быстрее, чем настройка сетки для одного элемента. Flexbox выигрывает в задачах с одной осью.
Использование Flexbox для макетов целых страниц: Как только у вас появляется более двух компонентов, которые должны соотноситься друг с другом позиционно (заголовок + боковая панель + контент + футер), отсутствие второй оси у Flexbox становится проблемой. Grid справляется с этим с помощью именованных областей.
Использование Flexbox column как замены строкам Grid: <flex-direction: column> позволяет элементам складываться вертикально, но вы теряете возможность выравнивать контент одновременно по нескольким столбцам. Если вы думаете о столбцах — переходите на Grid.
Использование обоих вместе
Grid и Flexbox не исключают друг друга. Самый распространенный реальный патттерн — это Grid для макета уровня страницы, Flexbox внутри каждого раздела:
- Grid позиционирует боковую панель, заголовок и область основного контента
- Внутри навигации (которая находится в области заголовка) Flexbox отвечает за строку логотип + ссылки + кнопка призыва к действию
- Внутри основной области контента сетка карточек использует Grid для структуры столбцов
- Внутри каждой карточки Flexbox отвечает за макет иконки + текста + кнопки
Этот патттерн композиции — Grid для структуры, Flexbox для компонентов — это то, как работают внутри большинство современных CSS-фреймворков (Tailwind, Bootstrap).
Быстрая справка по свойствам
| Что вы хотите | Flexbox | Grid |
|---|---|---|
| Установить направление макета | <flex-direction> | <grid-template-columns/rows> |
| Пространство между элементами | <gap или <justify-content> | <gap> |
| Выравнивание по поперечной оси | <align-items> | <align-items> |
| Разместить элемент конкретно | Невозможно напрямую | <grid-column / <grid-row> |
| Сделать элементы одинаковой высоты | <align-items: stretch> | Поведение по умолчанию |
| Адаптивность без медиа-запросов | <flex-wrap: wrap + <flex-basis> | <auto-fill + <minmax()> |
Создавайте Flexbox-макеты визуально
Используйте наш визуальный CSS Flexbox Generator для создания flex-контейнеров, настройки выравнивания и мгновенного копирования сгенерированного CSS.