Grid template

grid-template-columns и grid-template-rows определяют структуру grid-сетки: количество и размер столбцов и строк.

Зачем нужно

Без grid-template сетка не знает, сколько столбцов и строк создавать. Эти свойства — основа любого grid-макета. Через них задаётся вся «скелетная» структура раскладки.

Где используется

  • Определение колонок и строк сетки
  • Адаптивные макеты через repeat, auto-fill, auto-fit
  • Гибкие размеры через fr, minmax, auto
  • Именованные линии для семантической навигации по сетке

Предпосылки

grid-template-columns

Фиксированные размеры

.grid {
  display: grid;
  grid-template-columns: 200px 300px 200px;
  /* 3 столбца: 200px, 300px, 200px */
}

Единица fr

fr (fraction) — доля оставшегося свободного пространства:

.grid {
  display: grid;
  width: 900px;

  /* 3 равных столбца по 300px */
  grid-template-columns: 1fr 1fr 1fr;

  /* Пропорции: 200px + 466px + 234px */
  grid-template-columns: 200px 2fr 1fr;
  /* 200px забирается, оставшиеся 700px делятся: 2/3 и 1/3 */
}

auto

auto — размер по содержимому (минимум) или по свободному месту:

.grid {
  grid-template-columns: auto 1fr auto;
  /* Первый и третий = по содержимому, средний = всё остальное */
}

Смешанные единицы

.grid {
  grid-template-columns: 250px 1fr 30%;
  /* Сайдбар 250px, контент — гибкий, правая панель 30% */
}

repeat — повторение паттерна

.grid {
  /* 6 одинаковых столбцов */
  grid-template-columns: repeat(6, 1fr);

  /* То же, что: 1fr 1fr 1fr 1fr 1fr 1fr */
}

/* Повторение паттерна */
.grid-pattern {
  grid-template-columns: repeat(3, 100px 1fr);
  /* = 100px 1fr 100px 1fr 100px 1fr */
}

/* 12-колоночная система */
.grid-12 {
  grid-template-columns: repeat(12, 1fr);
  gap: 20px;
}

minmax — ограничение размеров

.grid {
  grid-template-columns: minmax(200px, 300px) 1fr minmax(150px, 1fr);
  /* Первый столбец: не меньше 200px, не больше 300px */
  /* Третий: не меньше 150px, растёт как 1fr */
}

/* Строки с минимальной высотой */
.grid {
  grid-template-rows: minmax(100px, auto);
  /* Минимум 100px, растёт под содержимое */
}

Комбинация repeat + minmax

/* Адаптивная сетка карточек */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
}

auto-fill vs auto-fit

auto-fill — заполняет пустыми треками

.grid-fill {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  /* Создаёт столько столбцов, сколько влезет.
     Если элементов меньше — остаются пустые треки */
}

auto-fit — схлопывает пустые треки

.grid-fit {
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  /* Пустые треки схлопываются до 0.
     Элементы растягиваются на всё пространство */
}

Разница видна при малом количестве элементов:

  • auto-fill: 2 элемента в 4-колоночной сетке → 2 карточки + 2 пустых места
  • auto-fit: 2 элемента → 2 карточки растянуты на всю ширину

grid-template-rows

.grid {
  display: grid;
  grid-template-columns: 1fr;

  /* Фиксированные строки */
  grid-template-rows: 80px 1fr 60px;
  /* Header 80px, content гибкий, footer 60px */

  /* Минимальная высота страницы */
  min-height: 100dvh;
}

/* Множество одинаковых строк */
.grid-rows {
  grid-template-rows: repeat(5, 100px);
  /* 5 строк по 100px */
}

Именованные линии

.layout {
  display: grid;
  grid-template-columns:
    [sidebar-start] 250px
    [sidebar-end content-start] 1fr
    [content-end aside-start] 300px
    [aside-end];

  grid-template-rows:
    [header-start] 80px
    [header-end body-start] 1fr
    [body-end footer-start] 60px
    [footer-end];
}

/* Размещение по именам линий */
.header {
  grid-column: sidebar-start / aside-end;
  grid-row: header-start / header-end;
}

.sidebar {
  grid-column: sidebar-start / sidebar-end;
  grid-row: body-start / body-end;
}

.content {
  grid-column: content-start / content-end;
  grid-row: body-start / body-end;
}

Сокращённое свойство grid-template

.grid {
  /* grid-template: rows / columns */
  grid-template: 80px 1fr 60px / 250px 1fr;

  /* То же, что: */
  grid-template-rows: 80px 1fr 60px;
  grid-template-columns: 250px 1fr;
}

Практические примеры

Сетка товаров

.products {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 24px;
  padding: 20px;
}

.product-card {
  border: 1px solid #e0e0e0;
  border-radius: 12px;
  overflow: hidden;
}

Holy Grail Layout

.page {
  display: grid;
  grid-template-columns: minmax(200px, 250px) 1fr minmax(200px, 300px);
  grid-template-rows: auto 1fr auto;
  min-height: 100dvh;
}

.header { grid-column: 1 / -1; }
.footer { grid-column: 1 / -1; }

Адаптивный 12-колоночный грид

.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 20px;
}

.col-4 { grid-column: span 4; }
.col-6 { grid-column: span 6; }
.col-8 { grid-column: span 8; }
.col-12 { grid-column: span 12; }

@media (max-width: 768px) {
  .col-4,
  .col-6,
  .col-8 {
    grid-column: span 12; /* На мобильных — на всю ширину */
  }
}

Частые ошибки

  1. 1fr не равен 100%fr работает с оставшимся пространством после фиксированных размеров
  2. minmax(0, 1fr) vs 1fr1fr = minmax(auto, 1fr), поэтому столбец не сожмётся меньше содержимого:
    /* Длинное слово может сломать сетку */
    grid-template-columns: 1fr 1fr;
    
    /* Исправление */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    
  3. auto-fill с max-content — нужен minmax, иначе не будет создавать дополнительные треки
  4. Забыли gap — элементы слипаются без промежутков

Практика

  • Создать 3-колоночную сетку с 1fr 2fr 1fr
  • Сделать адаптивную сетку через repeat(auto-fill, minmax(250px, 1fr))
  • Сравнить auto-fill и auto-fit с 2 элементами
  • Создать именованные линии и разместить по ним элементы
  • Реализовать 12-колоночную систему

Связанные темы

  • Основы Grid — базовые понятия grid
  • Grid areas — альтернативный способ через именованные области
  • Grid auto flow — неявные строки и столбцы
  • min() max() clamp() — функции для адаптивных размеров

Ресурсы