CSS Grid вглубь: areas, minmax, auto-fill
Поднимаемся над «просто колонками»: именованные области, гибкие треки и адаптивные сетки без медиазапросов.
CSS Grid — это двумерная система раскладки: вы одновременно управляете строками и столбцами, описывая сетку треков, а элементы расставляете по линиям или по именованным областям.
Зачем это знать на практике
Базового display: grid и пары колонок хватает для простых случаев. Но реальные макеты дышат: меню сворачивается, контента то много, то мало, ширина экрана непредсказуема. Если вы умеете описать сетку через minmax(), auto-fill и fr, то целая адаптивная галерея карточек умещается в одну строку CSS — без единого медиазапроса. А grid-template-areas превращает раскладку страницы в наглядную ASCII-карту, которую видно прямо в коде. Это экономит десятки строк и делает вёрстку устойчивой к изменениям контента.
Единица fr и распределение свободного места
Единица fr (fraction) — сердце Grid. Она означает «доля свободного пространства, оставшегося после вычитания фиксированных размеров и зазоров». Запись grid-template-columns: 1fr 2fr делит свободное место в пропорции 1 к 2: вторая колонка вдвое шире первой.
.layout {
display: grid;
/* боковая панель фиксирована, контент забирает остаток */
grid-template-columns: 240px 1fr;
gap: 24px;
}
Важно: fr считается после gap, поэтому зазоры никогда не «вылезают» за контейнер. И ещё тонкость — 1fr по умолчанию имеет минимальный размер auto, то есть трек не сожмётся уже своего содержимого. Это частый источник переполнения, к которому мы вернёмся в разделе про ошибки.
repeat() и повторяющиеся треки
Писать 1fr 1fr 1fr 1fr утомительно. Функция repeat() повторяет шаблон треков:
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr); /* четыре равные колонки */
gap: 16px;
}
/* можно повторять не одно значение, а группу */
.alt {
grid-template-columns: repeat(3, 200px 1fr); /* 6 колонок: узкая+широкая ×3 */
}
minmax(): гибкость с границами
Функция minmax(min, max) задаёт треку диапазон. Классика — колонка, которая не уже 200px, но с радостью растягивается: minmax(200px, 1fr). Минимум защищает от схлопывания, максимум 1fr позволяет занять свободное место.
.sidebar-content {
display: grid;
/* сайдбар от 180 до 280px, контент — остаток */
grid-template-columns: minmax(180px, 280px) 1fr;
gap: 24px;
}
Особое значение min-content внутри minmax спасает узкие колонки от переполнения: minmax(min-content, 1fr) разрешает треку сжаться до самого длинного неразрывного слова, но не уже.
auto-fill против auto-fit: галерея в одну строку
Самый эффектный приём Grid — адаптивная сетка карточек без медиазапросов. Ключевые слова auto-fill и auto-fit внутри repeat() сами вычисляют, сколько колонок поместится:
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 20px;
}
Браузер берёт ширину контейнера и набивает в неё столько колонок шириной минимум 220px, сколько влезет; при сужении окна число колонок уменьшается само. Разница между ключевыми словами проявляется, когда карточек меньше, чем влезает колонок:
| Значение | Поведение при нехватке элементов |
auto-fill | создаёт пустые «фантомные» треки — карточки прижаты влево, справа пустота |
auto-fit | схлопывает пустые треки в ноль — существующие карточки растягиваются на всю ширину |
Правило простое: хотите, чтобы немногие карточки растянулись на весь ряд — берите auto-fit; хотите сохранить «исходную» ширину и выравнивание по сетке — auto-fill.
grid-template-areas: раскладка как ASCII-карта
Именованные области — самый читаемый способ собрать макет страницы. Вы рисуете сетку строками-строками, а элементам присваиваете имя области:
.page {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100vh;
gap: 16px;
}
.page > header { grid-area: header; }
.page > nav { grid-area: sidebar; }
.page > main { grid-area: main; }
.page > footer { grid-area: footer; }
Точка . в кавычках обозначает пустую ячейку. Все области должны образовывать прямоугольник — нельзя задать L-образную область, браузер просто проигнорирует такую раскладку. Зато перестроить макет под мобильный — это переписать одну карту в медиазапросе, не трогая HTML.
Именованные линии и выравнивание
Линии сетки можно именовать прямо в шаблоне, в квадратных скобках, и затем ссылаться на имена вместо номеров:
.grid {
display: grid;
grid-template-columns: [start] 1fr [content-start] 3fr [content-end] 1fr [end];
}
.hero { grid-column: content-start / content-end; }
Выравнивание в Grid — две оси и четыре свойства. По строке (инлайн-ось) работают justify-items и justify-content, по столбцу (блочная ось) — align-items и align-content. *-items выравнивают содержимое внутри ячеек, а *-content распределяют саму сетку в контейнере, когда треки уже всего места. Отдельной ячейке можно переопределить выравнивание через justify-self / align-self.
.grid {
display: grid;
grid-template-columns: repeat(3, 100px);
justify-content: space-between; /* раскидать колонки по ширине */
align-items: center; /* центрировать содержимое ячеек по вертикали */
}
Как это работает под капотом
Алгоритм Grid выполняется в несколько проходов. Сначала браузер строит явную сетку из grid-template-*. Если элементов больше, чем ячеек, добавляются неявные треки, чьи размеры задаёт grid-auto-rows / grid-auto-columns (по умолчанию auto). Затем идёт размер треков: фиксированные значения резервируются первыми, далее распределяется содержимое для auto и min/max-content, и только в конце оставшееся место делится между fr пропорционально их весам. Поэтому fr — это всегда «остаток», а не абсолютная доля ширины: добавьте фиксированную колонку, и доли fr пересчитаются. Понимание порядка проходов объясняет, почему fr-колонка иногда не сжимается: её базовый минимум — auto, то есть размер контента, и до дележа остатка она уже «застолбила» это место.
Частые ошибки
Переполнение из-за минимального auto у fr и 1fr. Длинное слово, картинка или pre внутри 1fr-трека раздувают его шире контейнера, и появляется горизонтальная прокрутка. Лечится заменой на minmax(0, 1fr) — нулевой минимум разрешает треку сжаться.
Путают auto-fill и auto-fit. Берут auto-fill и удивляются, почему две карточки не растянулись на весь ряд. Для растяжения нужен auto-fit.
Незамкнутый прямоугольник в areas. Если именованная область образует не прямоугольник (например, «лесенку»), вся grid-template-areas игнорируется без ошибки в консоли — макет молча ломается.
Путают *-items и *-content. Ставят justify-content: center, ожидая центрирования текста в ячейках, а это центрирует всю сетку. За содержимое ячеек отвечают justify-items / align-items.
Итоги
frделит оставшееся место после фиксированных треков иgap; у него минимумauto.repeat()сокращает повторы,minmax()задаёт треку диапазон «min–max».repeat(auto-fill, minmax(220px, 1fr))— адаптивная галерея без медиазапросов;auto-fitрастягивает немногие элементы,auto-fillоставляет пустые треки.grid-template-areasописывает макет читаемой картой; области обязаны быть прямоугольными.*-itemsвыравнивают содержимое ячеек,*-content— всю сетку; против переполнения помогаетminmax(0, 1fr).