CSS Grid
Зачем это нужно
Flexbox раскладывает элементы в одну линию (ряд или колонку). А если нужна сетка — строки и колонки одновременно? Галерея фото, плитка новостей, макет «шапка — меню — текст — подвал». Для этого есть CSS Grid. Если flex — это бусы на нитке, то grid — шахматная доска.
Включаем сетку
<style>
.grid {
display: grid;
grid-template-columns: 100px 200px 100px;
gap: 10px;
}
.grid div { background: skyblue; padding: 20px; }
</style>
<div class="grid">
<div>1</div><div>2</div><div>3</div>
<div>4</div><div>5</div><div>6</div>
</div>
Результат: две строки по три блока; средняя колонка вдвое шире боковых; между всеми блоками 10px.
Строки мы не задавали — они создаются сами, когда элементы не влезают в первую строку.
grid-template-columns перечисляет ширины колонок через пробел.
Единица fr
fr (fraction, доля) — доля свободного места:
.grid { display: grid; grid-template-columns: 1fr 2fr 1fr; }
Результат: три колонки, средняя вдвое шире; вместе они всегда занимают всю ширину контейнера и сами подстраиваются, если окно сузить.
Можно смешивать: 200px 1fr — левая колонка 200px, правая — всё остальное.
repeat и minmax
Чтобы не писать 1fr 1fr 1fr 1fr:
.grid { grid-template-columns: repeat(4, 1fr); }
minmax(мин, макс) задаёт размер «от и до». Знаменитый приём «столько колонок, сколько влезет»:
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
}
Результат: карточки не уже 200px; на широком экране — 5 в ряд, на телефоне — 1. Без единого медиазапроса.
Строки
.grid { grid-template-rows: 80px 1fr 60px; }
auto — высота по содержимому. Строки и колонки вместе образуют ячейки, а линии между ними нумеруются
с 1: у трёх колонок — линии 1, 2, 3, 4.
Растяжение на несколько ячеек
Элементу можно сказать, сколько ячеек он занимает:
.big {
grid-column: span 2; /* 2 колонки */
grid-row: span 2; /* 2 строки */
}
.wide {
grid-column: 1 / 4; /* от линии 1 до линии 4 = 3 колонки */
}
.full {
grid-column: 1 / -1; /* от первой до последней линии — на всю ширину */
}
Результат: .big — квадрат 2×2 ячейки, остальные элементы обтекают его; .full растянут на всю строку.
Именованные области
Самый наглядный способ — нарисовать макет словами:
.page {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"nav main"
"footer footer";
}
.page header { grid-area: header; }
.page nav { grid-area: nav; }
.page main { grid-area: main; }
.page footer { grid-area: footer; }
Результат: шапка на всю ширину, ниже слева меню 200px и справа текст, внизу подвал на всю ширину.
Каждая строка в кавычках — одна строка сетки, слова — ячейки. Одинаковые слова рядом сливаются в одну
область. Точка . — пустая ячейка. Области должны быть прямоугольными.
Grid или Flexbox?
- Flexbox — когда элементы идут в одну линию и их размер зависит от содержимого: меню, кнопки, шапка.
- Grid — когда нужна сетка с ровными колонками и строками: галерея, макет страницы.
Их часто совмещают: страница — grid, шапка внутри — flex.
Как это работает внутри
Браузер сначала строит «невидимую решётку» по grid-template-columns и grid-template-rows
(колонки в fr делят то, что осталось после пикселей). Затем раскладывает детей по ячейкам:
по очереди слева направо, а элементы с span, номерами линий или grid-area — на их места.
Посмотреть решётку можно в инструментах разработчика: рядом с контейнером есть значок grid.
Частые ошибки
display: gridу детей. Сетка включается у контейнера.1frи%вперемешку сgap.25% 25% 25% 25%плюсgapне влезет в ширину. Сfrтакого нет.- Опечатка в именах областей.
grid-area: hedaer— элемент молча уйдёт в автоматическую ячейку. - Непрямоугольная область.
"a a" "a b"— областьaбуквой «Г» — так нельзя, весь шаблон сломается. - Ставят
widthколонкам у детей. Ширину колонок задаёт контейнер, а не элементы.
Шпаргалка
| Свойство | Что делает |
|---|---|
display: grid |
включить сетку |
grid-template-columns: 1fr 2fr |
колонки |
grid-template-rows: auto 1fr |
строки |
repeat(3, 1fr) |
повторить |
repeat(auto-fill, minmax(200px, 1fr)) |
сколько влезет |
gap: 10px |
промежутки |
grid-column: span 2 / 1 / -1 |
растянуть на 2 колонки / на всю ширину |
grid-row: span 2 |
растянуть на 2 строки |
grid-template-areas + grid-area |
макет по именованным областям |