HTML/CSSMiddleTechnical

Что такое 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».

Sources

Related topics