CSS Grid: настоящая сетка
Колонки и строки сразу, единица fr, repeat и minmax, именованные области — и раскладка страницы, которую видно прямо в коде.
Что ты научишься делать
- Разложишь элементы по колонкам и строкам одновременно
- Сделаешь сетку, которая сама подстраивается под ширину экрана
- Соберёшь раскладку «шапка / меню / контент / подвал» через grid-template-areas
#Флексы вдоль оси, гриды — по сетке
Flexbox работает с одной осью: ряд или колонка. Grid работает с двумя сразу: он задаёт координатную сетку, а элементы расставляются по её клеткам.
Отсюда простое правило выбора: ряд элементов — флексы, раскладка страницы или галерея — грид. И то и другое можно вкладывать друг в друга сколько угодно.
#Первая сетка
.grid { display: grid; grid-template-columns: 200px 200px 200px; gap: 16px;}Строки создаются автоматически: элементы заполняют первую строку, потом переходят на следующую. Задавать grid-template-rows обычно не нужно.
#fr — доля свободного места
fr (fraction) — единица, которая существует только в гридах. Она означает долю оставшегося места после того, как учтены фиксированные размеры и отступы.
grid-template-columns: 1fr 1fr 1fr; /* три равные колонки */grid-template-columns: 2fr 1fr; /* первая вдвое шире второй */grid-template-columns: 240px 1fr; /* фиксированное меню + резиновый контент */grid-template-columns: 1fr 3fr 1fr; /* поля по краям, контент в центре */#repeat, minmax и авторазмещение
/* Двенадцать одинаковых колонок — писать 1fr двенадцать раз необязательно */grid-template-columns: repeat(12, 1fr);/* Колонка не уже 200px, дальше растягивается */grid-template-columns: repeat(3, minmax(200px, 1fr));/* Сколько поместится — столько и будет. Медиазапросы не нужны */grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));Последняя строка — самый полезный приём во всём гриде. Браузер сам считает, сколько колонок шириной не меньше 220 пикселей поместится в контейнер, и раскладывает элементы. На широком экране их будет пять, на телефоне — одна.
auto-fit и auto-fill отличаются одним: когда элементов меньше, чем колонок, auto-fit схлопывает пустые колонки и растягивает существующие, а auto-fill оставляет пустые места.
#Размещение по линиям
Линии сетки нумеруются с единицы. Элемент можно поставить в конкретное место, указав, между какими линиями он живёт.
.featured { grid-column: 1 / 3; /* от линии 1 до линии 3, то есть две колонки */ grid-row: 1 / 3; /* и две строки */}.wide { grid-column: span 2; /* просто «занять две», где бы ни оказался */}.full { grid-column: 1 / -1; /* от первой линии до последней: во всю ширину */}#Именованные области: раскладку видно в коде
Самая наглядная часть грида. Ты рисуешь схему прямо в CSS — строками текста, где каждое слово это одна клетка.
.layout { display: grid; grid-template-columns: 220px 1fr; grid-template-areas: "header header" "nav main" "footer footer"; gap: 16px; min-height: 100vh;}.layout__header { grid-area: header; }.layout__nav { grid-area: nav; }.layout__main { grid-area: main; }.layout__footer { grid-area: footer; }Схему видно глазами: шапка на всю ширину, под ней меню и контент, внизу подвал. Чтобы поменять раскладку на телефоне, достаточно переписать эти три строки — сами блоки трогать не нужно.
Точка вместо имени означает пустую клетку.
#Промежутки и неявные ряды
Колонки ты объявляешь сам, а ряды чаще всего появляются по мере надобности: элементов стало больше — сетка добавила ещё одну строку. Такие строки называются неявными, и по умолчанию каждая подстраивается под свой контент.
Когда нужно, чтобы все ряды были одной высоты, есть grid-auto-rows. С minmax() получается удобное сочетание: не ниже заданного, но растёт, если текста много.
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* каждая новая строка — минимум 160px, но тянется под контент */ grid-auto-rows: minmax(160px, auto); gap: 16px;}#Выравнивание внутри клеток
| Свойство | Где пишется | Что делает |
|---|---|---|
justify-items | Контейнеру | Выравнивает содержимое клеток по горизонтали |
align-items | Контейнеру | То же по вертикали |
place-items | Контейнеру | Сокращение для двух предыдущих |
justify-self / align-self | Элементу | Переопределяет выравнивание для одной клетки |
justify-content / align-content | Контейнеру | Двигает всю сетку целиком, если она меньше контейнера |
Где спотыкаются почти все
Колонки заданы в процентах вместе с gap
Почему Проценты считаются от ширины контейнера и не учитывают промежутки. Сумма получается больше 100 %, и последняя колонка переносится.
Как надо Используй fr: он делит место, которое осталось после вычета всех отступов.
display: grid написан элементу вместо контейнера
Почему Сеткой становится тот, кому задано свойство. Дети раскладываются только у контейнера.
Как надо Свойство — родителю, как и во флексах.
В grid-template-areas строки разной длины
Почему Схема обязана быть прямоугольной: во всех строках одинаковое число слов. Иначе всё правило игнорируется целиком.
Как надо Пересчитай слова в каждой строке. Пустые клетки обозначай точкой.
auto-fill вместо auto-fit при малом числе элементов
Почему Две карточки на широком экране прижмутся влево, а справа останется пустота из «призрачных» колонок.
Как надо Бери auto-fit: пустые колонки схлопнутся, а существующие растянутся.
- Грид-контейнер grid container
- Элемент с
display: grid, задающий сетку для своих детей. - Дорожка track
- Колонка или строка сетки.
- fr fraction
- Доля свободного места после вычета фиксированных размеров и промежутков.
- minmax() minmax
- Задаёт дорожке минимальный и максимальный размер.
- Именованная область grid area
- Прямоугольный кусок сетки с именем, заданный в
grid-template-areas.
Проверь себя
Свободное место — это то, что осталось после фиксированных дорожек и всех промежутков. Оно делится между <code>fr</code>-дорожками пропорционально.
Это отзывчивая сетка без медиазапросов: количество колонок браузер считает сам под ширину контейнера.
Минус один означает последнюю линию сетки — сколько бы колонок в ней ни было.
Схема обязана быть прямоугольной. Если в строках разное число слов, браузер игнорирует всё правило целиком.
Одна ось — флекс, две оси — грид. Их постоянно вкладывают друг в друга: сетка страницы на гриде, шапка внутри — на флексе.
Задание
Раскладка страницы на областях
Собери раскладку через grid-template-areas:
- шапка на всю ширину;
- под ней слева меню фиксированной ширины 160px, справа контент;
- подвал на всю ширину;
- расстояние между блоками не меньше 10px;
- вся раскладка не ниже 320px.
Подсказка 1
Схема пишется строками, по одному слову на клетку: "header header" / "nav main" / "footer footer".
Подсказка 2
Каждому блоку нужно назначить его область: .layout__header { grid-area: header; }
Показать решение
<div class="layout"> <header class="layout__header">Шапка</header> <nav class="layout__nav">Меню</nav> <main class="layout__main">Содержимое</main> <footer class="layout__footer">Подвал</footer></div>* { box-sizing: border-box; }.layout { display: grid; grid-template-columns: 160px 1fr; grid-template-areas: "header header" "nav main" "footer footer"; gap: 12px; min-height: 340px;}.layout__header { grid-area: header; background: #6544e0; color: #fff; }.layout__nav { grid-area: nav; background: #2b9c74; color: #fff; }.layout__main { grid-area: main; background: #f4f4f8; }.layout__footer { grid-area: footer; background: #14173a; color: #fff; }.layout > * { display: grid; place-items: center; padding: 14px; border-radius: 10px;}