Сетка в три строки
Задайте контейнеру display: grid и перечислите его колонки в grid-template-columns. Дочерние элементы заполняют ячейки по порядку, слева направо в русском, и новая строка начинается, когда колонки заполнены:
Семь элементов, три колонки: две полные строки и третья с элементом 7 в первой колонке. Все колонки одинаковой ширины, и все элементы в строке одинаковой высоты, поэтому края выровнены в обоих направлениях. Именно это grid добавляет к flexbox.
Песочница grid
Введите любое значение grid-template-columns или кликните по готовому варианту. Ниже показаны ширины колонок, которые вычислил браузер (через getComputedStyle), и сколько строк понадобилось элементам:
На что посмотреть: 1fr 2fr делает вторую колонку ровно вдвое шире первой. 200px 1fr сохраняет 200px и отдает остальное второй колонке. auto 1fr auto задает внешним колонкам ширину по содержимому. repeat(4, 100px) оставляет пустое место в конце, потому что ничего не тянется. Невалидное значение, например 1fr 2, игнорируется, и сетка сохраняет последнее валидное.
Единица fr
fr означает «одна доля свободного пространства». Браузер сначала вычитает фиксированные колонки (px, rem, %, содержимое auto) и промежутки, а затем делит остаток между колонками fr по их числам.
grid-template-columns в контейнере 600px без промежутков | Ширины колонок |
|---|---|
1fr 1fr 1fr | 200, 200, 200 |
1fr 2fr | 200, 400 |
100px 1fr 1fr | 100, 250, 250 |
1fr 50% | 300, 300 |
fr это не %: проценты вместе с промежутками могут дать больше 100% и переполнить контейнер, а колонки fr всегда делят только то, что осталось после промежутков.
repeat(), minmax() и адаптивная сетка без медиазапросов
repeat(4, 1fr) это 1fr 1fr 1fr 1fr. minmax(120px, 1fr) это колонка, которая никогда не бывает уже 120px и растет, забирая свою долю. Соедините их с auto-fill или auto-fit вместо числа, и сетка создаст столько колонок, сколько поместится:
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 16px;
}
Одно объявление дает столько колонок шириной не меньше 180px, сколько вмещает контейнер: несколько на широком экране, одну на телефоне, без медиазапросов. Разница между auto-fill и auto-fit видна, когда элементов меньше, чем колонок:
В контейнер помещается пять колонок по 100px. auto-fill сохраняет все пять, поэтому A, B и C по 112px, а две пустые колонки остаются. auto-fit схлопывает пустые, и три элемента растягиваются примерно до 187px каждый.
Размещение элементов: grid-column и grid-row
Линии сетки нумеруются с 1 от начального края. grid-column: 1 / 3 значит «от линии 1 до линии 3», то есть две колонки. span 2 значит «две колонки от того места, где элемент окажется», а -1 это последняя линия:
Темный элемент заполняет всю первую строку. Синий занимает блок 2 на 2, янтарный две строки. Элементы a и b сами заполняют оставшиеся ячейки: grid ставит каждый элемент, какой может, в следующую свободную ячейку. grid-auto-rows: 60px задает высоту строк, которые вы не объявили в grid-template-rows.
grid-template-areas: дайте имена частям раскладки
Для раскладки страницы назовите области и нарисуйте их текстом. Каждая строка в кавычках это строка сетки, каждое слово ячейка, а элемент присоединяется к области через grid-area:
Шапка и подвал охватывают обе колонки, потому что их имена заполняют обе ячейки своих строк. Средняя строка 1fr, поэтому она забирает оставшуюся от 280px высоту. Чтобы сложить все в столбик на телефоне, медиазапросу достаточно перерисовать области в одну колонку: grid-template-areas: "header" "side" "main" "footer" с grid-template-columns: 1fr. Этот прием показан на странице про медиазапросы.
Выравнивание внутри ячеек
По умолчанию grid-элементы растягиваются на свою ячейку. Эти свойства двигают их внутри нее:
| Свойство | У кого | Что двигает |
|---|---|---|
justify-items | контейнер | каждый элемент вдоль строки (строчная ось) |
align-items | контейнер | каждый элемент вверх и вниз (блочная ось) |
place-items | контейнер | сокращение: place-items: center центрирует в обоих направлениях |
justify-self / align-self | элемент | один элемент |
justify-content / align-content | контейнер | весь набор дорожек, когда сетка меньше контейнера |
display: grid; place-items: center; это самый короткий способ выровнять один дочерний элемент по центру блока.
Grid или flexbox
Grid двумерный: вы задаете колонки (и строки), а содержимое заполняет их, поэтому все карточки в галерее одинаковой ширины даже в последней строке. Flexbox одномерный: элементы берут размер от содержимого вдоль одной линии. Они хорошо сочетаются: grid для страницы и галереи карточек, flexbox внутри каждой карточки для ее верхней строки. Вторая половина разобрана на странице про Flexbox CSS.
Порядок и доступность
grid-template-areas, grid-row, grid-column и order могут поставить элемент куда угодно, но программы чтения с экрана и клавиша Tab все равно следуют порядку HTML. Сохраняйте осмысленный порядок в коде (шапка, навигация, основное содержимое, подвал) и используйте grid, чтобы его расставить, а не чтобы исправлять бессмысленный порядок HTML.
Частые ошибки
display: gridу элементов. Его задают родителю; grid-элементами являются только прямые дочерние элементы.- Проценты вместе с промежутками.
grid-template-columns: 50% 50%плюсgap: 16pxпереполняет контейнер на 16px. Используйте1fr 1fr. auto-fill, когда нуженauto-fit. При малом числе элементовauto-fillоставляет пустые колонки. Переключитесь наauto-fit, чтобы элементы растянулись.- Колонка
1frрастет больше своей доли. Колонка1frне сжимается уже самого длинного содержимого (длинного URL, широкого изображения). Используйтеminmax(0, 1fr), чтобы она могла сжиматься. - Области, которые не образуют прямоугольник. Каждая именованная область должна быть прямоугольником, а в каждой строке должно быть одинаковое число ячеек, иначе все объявление
grid-template-areasигнорируется. - Забыли, что линии нумеруются с 1. У трех колонок четыре линии:
1 / 4или1 / -1охватывает все три.
Часто задаваемые вопросы
Что такое CSS Grid?
Система раскладки, которая размещает элементы по строкам и колонкам одновременно. Вы задаете контейнеру display: grid, описываете его колонки через grid-template-columns (и при желании строки), а прямые дочерние элементы по порядку заполняют ячейки.
Что означает 1fr в CSS Grid?
fr это доля свободного пространства grid-контейнера. grid-template-columns: 1fr 1fr 1fr дает три равные колонки, а 1fr 2fr делает вторую колонку вдвое шире первой. Сначала вычитаются фиксированные размеры и промежутки, а колонки fr делят то, что осталось.
Чем auto-fill отличается от auto-fit?
Оба создают столько колонок, сколько помещается. auto-fill сохраняет пустые колонки, поэтому несколько элементов остаются узкими и оставляют пустое место в конце строки. auto-fit схлопывает пустые колонки, и элементы растягиваются на всю строку. Если элементов достаточно, чтобы заполнить строку, оба выглядят одинаково.
Как растянуть grid-элемент на две колонки?
Задайте элементу grid-column: span 2 или укажите начальную и конечную линии: grid-column: 1 / 3 охватывает колонки 1 и 2. grid-column: 1 / -1 растягивает на всю ширину, потому что -1 это последняя линия.
Когда использовать grid вместо flexbox?
Grid, когда строки и колонки должны быть выровнены друг с другом: галереи карточек, формы с выровненными подписями, страница с шапкой, боковой панелью и подвалом. Flexbox для одной строки или колонки, элементы которой берут размер от содержимого, например для навигации.
grid-gap и gap это одно и то же?
Да. grid-gap, grid-row-gap и grid-column-gap это старые имена. Браузеры все еще принимают их как псевдонимы, но пишите gap, row-gap и column-gap, которые работают и во flexbox.