Адаптивные сетки

Вёрстка гридами включает ключевые слова 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 или что-то ещё для компенсации отсутствие промежутков, которые включены в грид-версию.

Автор: Йен Диксон
Последнее изменение: 22.02.2024