Основы Grid

CSS Grid Layout — двумерная система раскладки, позволяющая управлять расположением элементов одновременно по строкам и столбцам.

Зачем нужно

Grid — самый мощный инструмент CSS для создания макетов. В отличие от Flexbox (одномерный), Grid работает в двух измерениях: можно одновременно контролировать строки и столбцы. Это идеальный инструмент для макетов страниц, карточных сеток и дашбордов.

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

  • Макеты страниц (header, sidebar, content, footer)
  • Карточные сетки (товары, статьи)
  • Дашборды с виджетами разного размера
  • Формы (label + input в колонках)
  • Галереи изображений

Предпосылки

Терминология Grid

Grid Container (display: grid)
┌─────────────────────────────────────────────┐
│    column 1      column 2      column 3     │
│  ┌───────────┬───────────┬───────────┐      │
│  │           │           │           │ row 1 │
│  │  cell     │  cell     │  cell     │      │
│  │           │           │           │      │
│  ├───────────┼───────────┼───────────┤      │
│  │           │           │           │ row 2 │
│  │  cell     │  cell     │  cell     │      │
│  │           │           │           │      │
│  └───────────┴───────────┴───────────┘      │
│  ↑           ↑           ↑           ↑      │
│  line 1    line 2     line 3     line 4     │
└─────────────────────────────────────────────┘
  • Grid Container — элемент с display: grid
  • Grid Item — прямой потомок контейнера
  • Grid Line — линия, разделяющая строки/столбцы (нумерация с 1)
  • Grid Track — строка или столбец
  • Grid Cell — пересечение одной строки и одного столбца
  • Grid Area — прямоугольник из одной или нескольких ячеек
  • Gap — промежуток между треками

Создание Grid-контейнера

.container {
  display: grid;
}

/* Или inline-grid */
.inline-container {
  display: inline-grid;
}

Все прямые потомки автоматически становятся grid-элементами:

<div class="container">
  <div>Item 1</div>   <!-- grid item -->
  <div>Item 2</div>   <!-- grid item -->
  <div>Item 3</div>   <!-- grid item -->
  <span>Item 4</span> <!-- grid item -->
</div>

Определение треков

Столбцы и строки

.grid {
  display: grid;

  /* 3 столбца */
  grid-template-columns: 200px 1fr 200px;

  /* 2 строки */
  grid-template-rows: 100px auto;

  /* Промежутки */
  gap: 16px;
}

Единица fr (fraction)

fr — доля свободного пространства:

.grid {
  display: grid;

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

  /* Первый в 2 раза шире */
  grid-template-columns: 2fr 1fr 1fr;

  /* Фиксированный + гибкие */
  grid-template-columns: 250px 1fr 1fr;
  /* 250px для сайдбара, остальное делится поровну */
}

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

.grid {
  /* 4 столбца по 1fr */
  grid-template-columns: repeat(4, 1fr);

  /* 12-колоночная сетка */
  grid-template-columns: repeat(12, 1fr);

  /* Повторяющийся паттерн */
  grid-template-columns: repeat(3, 100px 1fr);
  /* = 100px 1fr 100px 1fr 100px 1fr */
}

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

.grid {
  grid-template-columns: minmax(200px, 1fr) 2fr 1fr;
  /* Первый столбец: минимум 200px, максимум 1fr */

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

auto-fill и auto-fit

/* auto-fill: создаёт столько столбцов, сколько влезет */
.grid {
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  /* Адаптивная сетка без медиа-запросов! */
}

/* auto-fit: то же, но пустые треки схлопываются */
.grid-fit {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

auto-fill оставляет пустые колонки если мало элементов. auto-fit растягивает элементы на всё пространство.

Gap (промежутки)

.grid {
  /* Одинаковый gap для строк и столбцов */
  gap: 20px;

  /* Разный: строки | столбцы */
  gap: 20px 30px;

  /* Отдельно */
  row-gap: 20px;
  column-gap: 30px;
}

Размещение элементов

По линиям

.item {
  /* Столбец: от линии 1 до линии 3 */
  grid-column-start: 1;
  grid-column-end: 3;

  /* Сокращённо */
  grid-column: 1 / 3;

  /* Строка: от 1 до 2 */
  grid-row: 1 / 2;

  /* Span — занять N ячеек */
  grid-column: 1 / span 2; /* от 1-й линии, 2 столбца */
  grid-row: span 3;        /* 3 строки от текущей позиции */
}

Отрицательные линии

.full-width {
  /* От первой до последней линии */
  grid-column: 1 / -1;
}

Базовый пример

<div class="page">
  <header class="header">Header</header>
  <nav class="sidebar">Sidebar</nav>
  <main class="content">Content</main>
  <footer class="footer">Footer</footer>
</div>
.page {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100dvh;
  gap: 0;
}

.header {
  grid-column: 1 / -1; /* На всю ширину */
  background: #1a1a2e;
  color: white;
  padding: 20px;
}

.sidebar {
  background: #f5f5f5;
  padding: 20px;
}

.content {
  padding: 20px;
}

.footer {
  grid-column: 1 / -1; /* На всю ширину */
  background: #333;
  color: white;
  padding: 20px;
}

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

  1. Grid только для прямых потомков — внуки не являются grid-элементами:
    <div class="grid">
      <div>  <!-- grid item -->
        <span>НЕ grid item</span>
      </div>
    </div>
    
  2. Забыли display: gridgrid-template-columns без него не работает
  3. fr с нулевым контентом1fr может схлопнуться если min-width по содержимому больше:
    /* Исправление */
    .grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    
  4. Путаница номеров линий — линий на 1 больше, чем столбцов (3 столбца = 4 линии)

Практика

  • Создать 3-колоночную сетку через grid-template-columns
  • Сделать адаптивную сетку через repeat(auto-fill, minmax)
  • Разместить элемент на несколько ячеек через grid-column: span
  • Собрать макет страницы: header + sidebar + content + footer
  • Проверить grid в DevTools (включить grid overlay)

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

Ресурсы