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;
}

Объяснение по шагам:

  1. display: flex превращает .toolbar в flex-контейнер, элементы внутри становятся flex-элементами.
  2. align-items: center выравнивает элементы по поперечной оси (обычно по вертикали, если направление row).
  3. 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; }

Объяснение по шагам:

  1. display: grid включает Grid-контекст.
  2. grid-template-columns: 260px 1fr создаёт две колонки: фиксированную и «резиновую», которая занимает остаток ширины.
  3. grid-template-rows: auto 1fr auto создаёт три строки: высота по контенту, затем «резиновая», затем снова по контенту.
  4. grid-template-areas описывает карту областей; отдельные элементы «прикрепляются» к областям через grid-area.
В Grid проще заранее описать структуру макета (строки/колонки/области), а затем раскладывать элементы по этой структуре, что часто делает код макета более читаемым.

Ключевые различия и выбор

Главное различие формулируется так:

  • Flexbox — про раскладку элементов вдоль одной ведущей оси и удобное выравнивание/распределение пространства.
  • Grid — про одновременный контроль строк и колонок, то есть про «сетку» как основу макета.

Важно понимать нюанс: у Flexbox есть перенос (flex-wrap), и визуально может получиться несколько строк, но модель по-прежнему ориентирована на поток и выравнивание по осям, а не на управление единой двумерной сеткой.
У Grid наоборот: сначала задаётся сетка, затем элементы размещаются по координатам/линиям/областям; это ближе к «планированию» макета.

Практическое правило выбора:

  • Если требуется ряд/колонка элементов, выравнивание, распределение свободного места, «прижатие» одного элемента к краю — чаще подходит Flexbox.
  • Если требуется макет с колонками и строками одновременно, «растянуть блок на 2 колонки», построить каркас страницы, задать области — чаще подходит Grid.
  • Если требуется и то и другое — обычно используется сочетание: внешняя сетка на Grid, внутренности компонентов на Flexbox.

Таблица отличий

КритерийFlexboxGrid
ИзмеренияОдна ведущая ось + выравнивание по второй; возможен перенос на линииДве оси одновременно: строки и колонки
Подход«Элементы и их размеры» определяют распределение пространства«Сетка» задаётся явно, элементы размещаются в неё
Типичные задачиМеню, панель кнопок, выравнивание в компоненте, центрированиеКаркас страницы, галерея, сложные сетки, области макета
РазмещениеВ первую очередь поток вдоль оси и выравниваниеЯвное/авто размещение по линиям, областям, координатам
СочетаниеЧасто используется внутри grid-элементовЧасто используется как внешний каркас страницы

Схема для запоминания осей

Flexbox (выбирается ведущая ось)
[ item ][ item ][ item ]  -> main axis
      |
      v
   cross axis (выравнивание)

Grid (две оси одновременно)
columns -> | 1 | 2 | 3 |
rows     v |---|---|---|
          |---|---|---|
Фраза «Flexbox — 1D, Grid — 2D» полезна на старте, но она не должна мешать анализу задачи: иногда «одномерная» часть (например, содержимое карточки) живёт внутри «двумерной» сетки карточек.

Практика: примеры и разбор

Пример 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;
}

Почему это логично:

  1. .cards — двумерная задача (ряды и колонки карточек), поэтому Grid.
  2. .card — линейная задача (содержимое сверху вниз), поэтому Flexbox.
  3. 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).