Это статья про CSS Grid Layout, о способе компоновки объектов на основе сетки (Grid), мне захотелось пройтись по азам и заново познакомиться с основными правилами изменения пользовательского интерфейса при использовании данной технологии.
Grid был специально создан для решения проблем с разработкой макета. В отличие от одномерного Flex, Grid работает со сложными двухмерными макетами, однако в современной веб-разработке оба способа хорошо работают вместе и нет необходимости сравнивать, какой из способов размещения объектов лучше, можно применить Grid, а можно Flex — по необходимости; мало того, одно спокойно вкладывается в другое и можно, например, одному или всем дочерним элементам Flexbox задать свойство grid
, которое будет самостоятельно работать уже внутри них самих.
Создание сетки в CSS
Для понимания общей картины стоит прежде всего посмотреть, как выглядит сетка в браузере и постараться понять смысл расположения элементов в ней, чтобы терминология гридов не казалась оторванной от действительности.
Это меню с главной страницы моего сайта. Сетка, в которой умещаются персонажи, содержит в себе обычные <li>
обычного списка. Браузер отображает пронумерованные горизонтальные и вертикальные полосы, которые создают ячейки — подобно самой обыкновенной сетке. Здесь была решена задача по распределению элементов меню таким образом, чтобы каждый персонаж находился на своём месте и на определённой высоте. Надо разобраться, при помощи каких команд добиться закрепления объектов на своих местах, для этого понадобиться освоить несколько правил.
Для наглядности напишу простой код HTML, и помещу в контейнер несколько однотипных объектов.
<content class="grid-box">
<div class="grid_1">
<p><span>1</span> Lorem ipsum dolor sit amet, <br>
consectetur adipiscing elit.</p>
</div>
<div class="grid_2">
<p><span>2</span> Lorem ipsum dolor sit amet, <br>
consectetur adipiscing elit.</p>
</div>
<div class="grid_3">
<p><span>3</span> Lorem ipsum dolor sit amet, <br>
consectetur adipiscing elit.</p>
</div>
<div class="grid_4">
<p><span>4</span> Lorem ipsum dolor sit amet, <br>
consectetur adipiscing elit.</p>
</div>
</content>
Оформлю (не добавляя внешние отступы вложенным элементам!) и добавим родительскому контейнеру свойство сетки:
.grid-box {
display: grid;
}
Пока ничего особенного не произошло, но видно, что в браузере появилась сетка:
Вертикальные линии, отделяют друг от друга колонки (как в таблице) и называются линиями колонок, они определяются свойством grid-template-columns
, горизонтальные — называются линиями рядов, за них отвечает свойство grid-template-rows
.
Сразу бросается в глаза, что в моём простом макете отсутствуют внешние отступы, которые я принципиально не задал, поэтому элементы прилипают друг к другу. Grid (как, впрочем, и Flex) позволяет задавать отступы, — здесь лучше говорить о «желобах» или просто о расстояниях, отделяющих один элемент от другого, — свойством gap
. Итак, задам моему родительскому контейнеру все перечисленные выше свойства:
.grid-box {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
gap: 2em;
}
Вот что должно получиться:
Как можно видеть, между дочерними объектами появились «желоба» шириной 2em.
Тут стоит отдельно поговорить об измерениях в Grid. И лучше всего начать с основной величины grid-разметки — 1fr. Дело в том, что в Grid своя особая манера задавать размеры, и они задаются самым разнообразным способом, простейший из которых величина fr, это одна доля свободного пространства в сетке; например, если в CSS написать grid-template-columns: 1fr 1fr 1fr 1fr
, — то все четыре объекта выстроятся в один ряд по горизонтали.
Очевидно, что это неудобно, мы же не станем писать десять раз 1fr, если объектов будет десять, поэтому была придумана команда repeat; код выше можно упростить и написать repeat(4, 1fr)
— эффект будет тот же. Также в моём CSS у рядов (grid-template-rows
) выставлено значение auto
, однако и здесь можно указывать количество рядов. Для примера в таблице стилей я просто поменяю местами значения колонок и рядов, однако вместо четырёх укажу семь рядов, вот так:
.grid-box {
display: grid;
grid-template-columns: auto;
grid-template-rows: repeat(7, 1fr);
gap:2em;
}
Получается забавная картина: внизу появилось свободное пространство, разделённое на равные части. Дело в том, что весь родительский бокс, со свойством display: grid;
, выстроил сетку, добавив к существующим четырём (по количеству имеющихся объектов) три ряда, ведь я указал семь рядов.
А теперь изменю стиль родительского контейнера и задам другие величины:
.grid-box {
display: grid;
grid-template-columns: 10em auto 400px;
grid-template-rows: auto 200px auto;
gap: 0.5em;
}
Получился такой результат:
Здесь видно, что указывать размеры можно разным способом, в Grid нет каких-то особых ограничений, однако если размеры вложенных объектов будут больше, чем ячейки сетки, то они просто-напросто выпадут из неё.
Даже этих простых знаний хватит, чтобы начать работать с Grid, однако стоит иметь в виду, что объекты сетки не будут смещаться вниз при изменении размеров экрана, в отличие от Flex, поэтому при работе с сеткой в большинстве случаев приходится работать с медиазапросами.