Вёрстка гридами включает ключевые слова auto-fill и auto-fit, которые позволяют создать сетку с таким количеством дорожек заданного размера, которое поместится в контейнер. Это в результате даёт адаптивную сетку, в которой элементы сетки меняют свое положение при изменении размеров браузера.
Ключевое слово auto-fill
Пример использования auto-fill:
<!DOCTYPE html>
<html lang="ru">
<title>Пример</title>
<style>
#grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-gap: 2vw;
}
#grid > div {
font-size: 5vw;
padding: .5em;
background: gold;
text-align: center;
}
</style>
<div id="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
Необходимым является этот фрагмент:
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
Здесь устанавливается минимальный размер столбцов 150 пикселей, а максимальный — оставшееся пространство. Дорожки будут повторяться столько раз, сколько их поместится в контейнер.
Функция repeat() повторяет определение дорожки столько раз, сколько указано в первом параметре. При использовании auto-fill функция повторяет столько дорожек, сколько их поместится в контейнер.
Размер этих дорожек задаётся вторым параметром. В данном случае мы используем функцию minmax(150px, 1fr) для указания, что минимальный размер столбца составляет 150px, а максимальный 1fr.
Ключевое слово auto-fit
Ключевое слово auto-fit работает почти так же, как auto-fill. Разница в том, что auto-fit сжимает все пустые дорожки в конце компоновки, а вот auto-fill нет.
Лучший способ продемонстрировать это — сравнить два варианта:
<!DOCTYPE html>
<html lang="ru">
<title>Пример</title>
<style>
.grid {
display: grid;
grid-gap: 2vw;
border: 1px solid black;
margin: 10px;
}
.grid > div {
font-size: 5vw;
padding: .5em;
background: gold;
text-align: center;
}
.auto-fill {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.auto-fit {
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
</style>
<div class="grid auto-fill">
<div>1</div>
<div>2</div>
</div>
<div class="grid auto-fit">
<div>1</div>
<div>2</div>
</div>
Использование всего двух небольших элементов сетки помогает продемонстрировать данную концепцию. Сетка с auto-fill сохраняет пустые дорожки в конце в заданном размере. Но auto-fit сжимает пустые дорожки, в результате чего заполненные дорожки растягиваются, заполняя собой всё пространство.
Гриды с медиа-запросами
Одна из самых сильных сторон вёрстки гридами заключается в том, что вы можете создать другой макет в течение нескольких секунд (как мы это уже видели ранее).
Поэтому гриды идеально подходят для медиа-запросов. Мы можем просто переставить значения в нашей ASCII-графике и указать медиа-запрос.
Вот пример:
<!DOCTYPE html>
<html lang="ru">
<title>Пример</title>
<style>
body {
display: grid;
grid-template-areas:
"header header header"
"nav article ads"
"footer footer footer";
grid-template-rows: 80px 1fr 70px;
grid-template-columns: 20% 1fr 15%;
grid-row-gap: 10px;
grid-column-gap: 10px;
height: 100vh;
margin: 0;
}
/* Макет для маленьких устройств/экранов */
@media all and (max-width: 575px) {
body {
grid-template-areas:
"header"
"article"
"ads"
"nav"
"footer";
grid-template-rows: 80px 1fr 70px 1fr 70px;
grid-template-columns: 1fr;
}
}
header, footer, article, nav, div {
padding: 1.2em;
background: gold;
}
#pageHeader {
grid-area: header;
}
#pageFooter {
grid-area: footer;
}
#mainArticle {
grid-area: article;
}
#mainNav {
grid-area: nav;
}
#siteAds {
grid-area: ads;
}
</style>
<body>
<header id="pageHeader">Шапка</header>
<article id="mainArticle">Статья</article>
<nav id="mainNav">Навигация</nav>
<div id="siteAds">Реклама</div>
<footer id="pageFooter">Подвал</footer>
</body>
На больших экранах это будет трёхколоночный макет, а на маленьких он сворачивается в одну колонку. Поэтому данный пример будет выглядеть по-разному в зависимости от размера вашего экрана. В большинстве случаев он будет свёрнут, так как область просмотра виджета примера небольшая.
В любом случае, вот соответствующий код для трёхколоночного макета (для более широких экранов):
grid-template-areas:
"header header header"
"nav article ads"
"footer footer footer";
А вот соответствующий код для «мобильной» версии:
grid-template-areas:
"header"
"article"
"ads"
"nav"
"footer";
Поэтому нужно просто переставить значения в свойстве grid-template-areas. В этом случае мы вставим «мобильную» версию в медиа-запрос, например, так:
@media all and (max-width: 575px) {
body {
grid-template-areas:
"header"
"article"
"ads"
"nav"
"footer";
grid-template-rows: 80px 1fr 70px 1fr 70px;
grid-template-columns: 1fr;
}
}
Обратите внимание, что нам также пришлось скорректировать значения свойств grid-template-rows и grid-template-columns, чтобы учесть новый макет. В частности, должна быть только одна колонка, и она должна занимать всё доступное пространство. А поскольку все элементы сетки будут располагаться друг под другом, мы явно задаём пять строк и их высоту.
Комбинирование гридов и блоков
В зависимости от ваших требований к макету, ничего не мешает поменять мобильную версию на display: block. Например, так:
@media all and (max-width: 575px) {
body {
display: block;
}
}
Это будет работать аналогично приведённому выше примеру, однако по умолчанию элементы будут располагаться в исходном порядке. В мобильной версии навигация располагается под рекламой, но если бы мы использовали display: block, то навигация оказалась бы выше рекламы.
Кроме того, если используется данный метод, вам, возможно, придётся добавить margin или что-то ещё для компенсации отсутствие промежутков, которые включены в грид-версию.