← назад к разделу

Flexbox раскладывает вдоль одной оси; Grid управляет двумя сразу — строками и колонками как единой сеткой. Это раскладка «сверху вниз»: сначала описываете сетку, потом расселяете в неё элементы. Каркасы страниц, галереи, формы в несколько колонок, дашборды — родная территория grid.

Треки и единица fr

.layout {
  display: grid;
  grid-template-columns: 240px 1fr;  /* сайдбар и резиновый контент */
  grid-template-rows: auto 1fr auto; /* шапка, растущая середина, подвал */
  gap: 16px;
}

grid-template-columns/rows описывают треки — колонки и строки. Размеры — любые: пиксели, проценты, auto (по контенту) и главная новинка — fr: доля оставшегося места. Сначала раздаются фиксированные треки и gap, остаток делится по fr-долям: 1fr 2fr — «в пропорции 1:2». Дети контейнера сами раскладываются по ячейкам слева направо, сверху вниз; строки, не описанные в шаблоне, создаются неявно (их высоту задаёт grid-auto-rows).

Повторы сворачивает repeat(): repeat(12, 1fr) — классическая 12-колоночная сетка одной записью.

Автосетка: адаптивность без медиазапросов

Самая знаменитая строчка grid:

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}

Читается так: «колонок — сколько влезет (auto-fit), каждая не уже 220px и растягивается на равную долю (minmax)». Сетка сама пересчитывает число колонок под ширину экрана: на телефоне одна, на мониторе пять — ни одного медиазапроса. Для галерей карточек это решение по умолчанию. (Сосед auto-fill отличается поведением при недоборе элементов: он сохраняет пустые колонки, auto-fit растягивает заполненные.)

Расселение: линии, span и области

Элемент можно поселить в конкретные ячейки — координатами линий (линии нумеруются с 1, их на одну больше, чем треков):

.hero {
  grid-column: 1 / 3;      /* от 1-й до 3-й линии = две колонки */
  grid-row: 1;
}
.wide { grid-column: span 2; } /* просто «шириной в 2 трека», где встанет */
.full { grid-column: 1 / -1; } /* -1 — последняя линия: на всю ширину */

А можно — по именам, через grid-template-areas: макет страницы рисуется прямо в CSS псевдографикой:

.page {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-areas:
    "sidebar header"
    "sidebar content"
    "sidebar footer";
}
.page > header { grid-area: header; }
.page > nav    { grid-area: sidebar; }

Шаблон областей — самодокументирующийся макет: перестроить страницу под мобильный — значит переписать «картинку» в медиазапросе, не трогая сами элементы. Точка означает пустую ячейку.

Выравнивание внутри ячеек — знакомая по flexbox пара, только имена симметричнее: justify-* — по строке (инлайн-ось), align-* — по колонке; *-items — для всех, *-self — для одного. Центрирование содержимого ячейки: place-items: center (шорткат align+justify).

Grid или flexbox?

Не конкуренты — разделение труда:

  • Grid — когда раскладка двумерная или должна быть выровнена между рядами: каркас страницы, форма «лейбл-поле» в колонках, галерея, где карточки стоят строго по сетке.
  • Flexbox — когда раскладка одномерная и размеры диктует контент: тулбар, меню, ряд кнопок, теги с переносом.

Практический маркер: если вы ловите себя на вложенных flex-обёртках ради выравнивания «через ряд» — это grid. Если пишете grid для одного ряда кнопок — это flex. Внутри grid-ячейки спокойно живёт flex-контейнер и наоборот: типичная страница — grid-каркас, flex-начинка.

И знакомая грабля работает и здесь: длинный контент не даёт колонке ужаться — у grid-детей то же min-width: auto, лечится min-width: 0 (или minmax(0, 1fr) прямо в шаблоне).

Коротко

  • Grid описывает сетку заранее: grid-template-columns/rows, треки в px/auto/fr; fr — доля остатка после фиксированных треков и gap.
  • repeat(auto-fit, minmax(220px, 1fr)) — адаптивная галерея без медиазапросов; запомнить наизусть.
  • Расселение: по линиям (grid-column: 1 / -1), по span, или по именованным областям — grid-template-areas рисует макет псевдографикой.
  • Grid — двумерное и выровненное между рядами; flex — одномерное от контента. Вложенные flex ради «выравнивания через ряд» — сигнал переходить на grid.
  • Переполнение колонок лечится minmax(0, 1fr) или min-width: 0.

Что почитать дальше

  • Flexbox — одномерный напарник grid.
  • Единицы и адаптивность — rem, vw, clamp и медиазапросы: чем измеряются треки.
  • Позиционирование — sticky-шапки внутри grid-каркасов.