Урок 09. Теория: колонки, ячейки, авто-сетки

📁 Раздел: Раскладка ⏱️ Время изучения: ~50 мин 🎯 Сложность: Средняя

⚡ Кратко

Grid работает сразу по двум осям: вы задаёте колонки (grid-cols-*), при необходимости строки (grid-rows-*), а элементы расставляются по ячейкам автоматически. Занять несколько ячеек — col-span-* и row-span-*. Число колонок легко меняется по брейкпоинтам, поэтому адаптивная сетка — это одна строка классов.

Колонки: главный класс

grid-cols-N делит контейнер на N равных колонок. «Равных» — значит по 1fr: свободное место делится поровну, а содержимое колонку не расширяет.

grid-cols-2

1
2

grid-cols-4

1
2
3
4
<div class="space-y-3">
  <p class="text-xs font-medium text-slate-500">grid-cols-2</p>
  <div class="grid grid-cols-2 gap-3">
    <div class="rounded bg-indigo-600 px-3 py-4 text-center text-xs text-white">1</div>
    <div class="rounded bg-indigo-600 px-3 py-4 text-center text-xs text-white">2</div>
  </div>
  <p class="text-xs font-medium text-slate-500">grid-cols-4</p>
  <div class="grid grid-cols-4 gap-3">
    <div class="rounded bg-indigo-600 px-3 py-4 text-center text-xs text-white">1</div>
    <div class="rounded bg-indigo-600 px-3 py-4 text-center text-xs text-white">2</div>
    <div class="rounded bg-indigo-600 px-3 py-4 text-center text-xs text-white">3</div>
    <div class="rounded bg-indigo-600 px-3 py-4 text-center text-xs text-white">4</div>
  </div>
</div>

Flex — это очередь: элементы становятся друг за другом и договариваются о месте по ходу. Grid — это заранее размеченная парковка: разметка есть, даже если машин нет, и каждая машина встаёт на своё место. Поэтому в grid колонки ровные независимо от содержимого, а во flex — «как получится».

Адаптивность — приставками

Самая полезная строка в вёрстке сеток выглядит так:

<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">…</div>

На мобильном — один столбец, от 640px — два, от 1024px — четыре. Растяните окно браузера и посмотрите на живой пример:

Карточка 1
Карточка 2
Карточка 3
Карточка 4
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
  <div class="rounded-lg border border-slate-200 bg-white p-4 text-sm text-slate-700">Карточка 1</div>
  <div class="rounded-lg border border-slate-200 bg-white p-4 text-sm text-slate-700">Карточка 2</div>
  <div class="rounded-lg border border-slate-200 bg-white p-4 text-sm text-slate-700">Карточка 3</div>
  <div class="rounded-lg border border-slate-200 bg-white p-4 text-sm text-slate-700">Карточка 4</div>
</div>

Объединение ячеек

col-span-2 заставляет элемент занять две колонки, row-span-2 — две строки. Так собираются «неровные» блоки дашбордов:

col-span-2
1
1
col-span-2
<div class="grid grid-cols-3 gap-3">
  <div class="col-span-2 rounded-lg bg-sky-600 px-3 py-6 text-center text-xs text-white">col-span-2</div>
  <div class="rounded-lg bg-slate-700 px-3 py-6 text-center text-xs text-white">1</div>
  <div class="rounded-lg bg-slate-700 px-3 py-6 text-center text-xs text-white">1</div>
  <div class="col-span-2 rounded-lg bg-sky-600 px-3 py-6 text-center text-xs text-white">col-span-2</div>
</div>

Особый случай — col-span-full: элемент занимает всю ширину сетки независимо от числа колонок. Удобно для заголовков внутри сетки.

Сетка без брейкпоинтов

Иногда число колонок вообще не нужно фиксировать: пусть браузер сам решит, сколько карточек влезет. Это делает auto-fit вместе с minmax():

Авто 1
Авто 2
Авто 3
Авто 4
<div class="grid gap-4 grid-cols-[repeat(auto-fit,minmax(200px,1fr))]">
  <div class="rounded-lg border border-slate-200 bg-white p-4 text-sm text-slate-700">Авто 1</div>
  <div class="rounded-lg border border-slate-200 bg-white p-4 text-sm text-slate-700">Авто 2</div>
  <div class="rounded-lg border border-slate-200 bg-white p-4 text-sm text-slate-700">Авто 3</div>
  <div class="rounded-lg border border-slate-200 bg-white p-4 text-sm text-slate-700">Авто 4</div>
</div>
<div class="grid gap-4 grid-cols-[repeat(auto-fit,minmax(200px,1fr))]">…</div>

Читается так: «сколько угодно колонок, каждая не уже 200px, свободное место делим поровну». Ни одного медиазапроса.

Строки и высота

Обычно строки создаются автоматически, но их можно задать явно: grid-rows-3, или управлять размером автоматических строк — auto-rows-min, auto-rows-fr. Полезно, когда карточки должны быть одинаковой высоты.

Короткий текст
Текст подлиннее, который занимает больше строк и растягивает всю строку сетки
Средний текст здесь
<div class="grid grid-cols-3 gap-3 auto-rows-fr">
  <div class="rounded-lg border border-slate-200 bg-white p-3 text-xs text-slate-700">Короткий текст</div>
  <div class="rounded-lg border border-slate-200 bg-white p-3 text-xs text-slate-700">Текст подлиннее, который занимает больше строк и растягивает всю строку сетки</div>
  <div class="rounded-lg border border-slate-200 bg-white p-3 text-xs text-slate-700">Средний текст здесь</div>
</div>

Каркас страницы

Grid хорош для крупной раскладки: сайдбар фиксированной ширины плюс растягивающийся контент.

Контент занимает остальное (1fr)
<div class="grid grid-cols-[200px_1fr] gap-4 rounded-lg border border-slate-200 bg-white p-3">
  <aside class="rounded-md bg-slate-100 p-3 text-xs text-slate-600">Сайдбар 200px</aside>
  <main class="rounded-md bg-slate-50 p-3 text-xs text-slate-600">Контент занимает остальное (1fr)</main>
</div>
<div class="grid grid-cols-[200px_1fr] gap-4">…</div>
Подчёркивание вместо пробела. В произвольных значениях пробелы запрещены — их заменяет _. Поэтому [200px_1fr], а не [200px 1fr].

Выравнивание внутри сетки

  • items-* — выравнивание содержимого ячеек по вертикали;
  • justify-items-* — по горизонтали;
  • place-items-center — сразу по обеим осям;
  • self-* и justify-self-* — для отдельного элемента.

Grid или Flex

ПризнакFlexGrid
Число осейоднадве
Размерыот содержимогоот разметки
Ровные колонкитребуют усилийпо умолчанию
Порядок «как встанет»данет, по ячейкам
Типичное применениестрока, панель, кнопкасетка, каркас страницы

Практическое правило: если элементы должны быть выровнены и по горизонтали, и по вертикали — берите grid. Если это просто ряд — flex проще.