Реализация распространённых макетов с помощью сетки
Чтобы завершить этот набор руководств по CSS-сетке, мы рассмотрим несколько различных макетов, которые продемонстрируют некоторые из различных техник, которые вы можете использовать при проектировании с помощью сетки. Мы рассмотрим пример, использующий grid-template-areas, типичную гибкую систему из 12 столбцов, а также список продуктов с автоматическим размещением. Как вы можете видеть из этого набора примеров, часто существует более одного способа достижения желаемого результата с помощью сетки. Выберите метод, который вы считаете наиболее полезным для решения проблем и реализации необходимых дизайнов.
Реагирующий макет с 1 до 3 гибких столбцов, использующий grid-template-areas
Многие веб-сайты являются вариантом этого типа макета, с контентом, сайдбарами, заголовком и футером. При адаптивном дизайне вы можете отобразить макет как одностолбцовый, добавив сайдбар на определённой точке перехода и затем использовать трёхстолбцовый макет для более широких экранов.
Мы создадим этот макет, используя именованные области шаблона, о которых мы узнали в руководстве Шаблоны областей сетки.
Разметка представляет собой контейнер с элементами для заголовка, футера, основного контента, навигации, сайдбара и блока для размещения рекламы.
<div class="wrapper">
<header class="main-head">The header</header>
<nav class="main-nav">
<ul>
<li><a href="">Nav 1</a></li>
<li><a href="">Nav 2</a></li>
<li><a href="">Nav 3</a></li>
</ul>
</nav>
<article class="content">
<h1>Main article area</h1>
<p>
In this layout, we display the areas in source order for any screen less
that 500 pixels wide. We go to a two column layout, and then to a three
column layout by redefining the grid, and the placement of items on the
grid.
</p>
</article>
<aside class="side">Sidebar</aside>
<div class="ad">Advertising</div>
<footer class="main-footer">The footer</footer>
</div>
Поскольку мы используем grid-template-areas для создания макета. Вне каких-либо медиа-запросов нам нужно назвать области. Мы называем области, используя свойство grid-area.
.main-head {
grid-area: header;
}
.content {
grid-area: content;
}
.main-nav {
grid-area: nav;
}
.side {
grid-area: sidebar;
}
.ad {
grid-area: ad;
}
.main-footer {
grid-area: footer;
}
Это не создаст макет, однако элементы теперь имеют имена, которые мы можем использовать для этого. Оставаясь вне медиа-запросов, мы теперь настроим макет для мобильной ширины. Здесь мы сохраняем всё в исходном порядке, пытаясь избежать разрыва между исходным кодом и отображением, как описано в руководстве Макет сетки и доступность. Мы не определили какие-либо дорожки столбцов или строк, но этот макет определяет один столбец, и строки будут создаваться по мере необходимости для каждого из элементов в неявной сетке.
.wrapper {
display: grid;
gap: 20px;
grid-template-areas:
"header"
"nav"
"content"
"sidebar"
"ad"
"footer";
}
После того, как наш мобильный макет готов, мы можем приступить к добавлению медиа-запроса, чтобы адаптировать этот макет для больших экранов с достаточным пространством для отображения двух столбцов.
@media (min-width: 500px) {
.wrapper {
grid-template-columns: 1fr 3fr;
grid-template-areas:
"header header"
"nav nav"
"sidebar content"
"ad footer";
}
nav ul {
display: flex;
justify-content: space-between;
}
}
Вы можете увидеть, как макет формируется в значении grid-template-areas. header занимает два столбца, как и nav. В третьей строке дорожки у нас есть sidebar рядом с content. В четвёртой строке дорожки я выбрал размещение моего ad контента — так что он появляется под сайдбаром, затем footer рядом с ним под контентом. Мы используем flexbox для навигации, чтобы отобразить её в строке со сдвигом.
Теперь мы можем добавить последнюю точку перехода, чтобы перейти к трёхстолбцовому макету.
@media (min-width: 700px) {
.wrapper {
grid-template-columns: 1fr 4fr 1fr;
grid-template-areas:
"header header header"
"nav content sidebar"
"nav content ad"
"footer footer footer";
}
nav ul {
flex-direction: column;
}
}
Трёхстолбцовый макет имеет два 1fr сайдбара и средний столбец, размер дорожки которого составляет 4fr. Это означает, что доступное пространство в контейнере разделено на 6 частей и распределено пропорционально нашим трём дорожкам — по одной части каждому сайдбару и 4 части центральному столбцу.
В этом макете мы отображаем nav в левом столбце рядом с content. В правом столбце у нас есть sidebar и под ним реклама (ad). footer теперь занимает всю нижнюю часть макета. Затем я использую flexbox для отображения навигации в виде столбца.
Это простой пример, но он демонстрирует, как мы можем использовать макет сетки для перестановки нашего макета для разных точек перехода. В частности, мы изменяем расположение блока ad, как это необходимо в моих разных столбцовых раскладках. Я считаю, что этот метод именованных областей очень полезен на этапе прототипирования, так как легко играть с расположением элементов. Вы всегда можете начать использовать сетку таким образом для прототипирования, даже если вы не можете полностью полагаться на неё в производстве из-за браузеров, которые посещают ваш сайт.
Гибкий макет из 12 столбцов
Если вы работали с одним из многочисленных фреймворков или систем сеток, вы, возможно, привыкли выстраивать свой сайт на гибкой сетке из 12 или 16 столбцов. Мы можем создать такую систему, используя CSS-сетку. В качестве простого примера давайте создадим гибкую сетку из 12 столбцов, которая имеет 12 дорожек столбцов с размером 1fr, все они имеют имя начальной линии col-start. Это означает, что у нас будет двенадцать линий сетки с именем col-start.
.wrapper {
display: grid;
grid-template-columns: repeat(12, [col-start] 1fr);
gap: 20px;
}
Чтобы продемонстрировать, как работает эта система сеток, я поместил четыре дочерних элемента внутри моего обертки.
<div class="wrapper">
<div class="item1">Start column line 1, span 3 column tracks.</div>
<div class="item2">
Start column line 6, span 4 column tracks. 2 row tracks.
</div>
<div class="item3">Start row 2 column line 2, span 2 column tracks.</div>
<div class="item4">
Start at column line 3, span to the end of the grid (-1).
</div>
</div>
Затем мы можем разместить их в сетке, используя именованные линии и ключевое слово span.
.item1 {
grid-column: col-start / span 3;
}
.item2 {
grid-column: col-start 6 / span 4;
grid-row: 1 / 3;
}
.item3 {
grid-column: col-start 2 / span 2;
grid-row: 2;
}
.item4 {
grid-column: col-start 3 / -1;
grid-row: 3;
}
Как описано в руководстве по именованным линиям, мы используем именованную линию для размещения нашего элемента. Поскольку у нас есть 12 линий, все с одинаковым именем, мы используем имя и затем индекс линии. Вы также можете использовать сам индекс линии, если хотите, и вообще избегать использования именованных линий.
Вместо задания конечного номера линии я выбрал указание количества дорожек, которое должен занимать этот элемент, используя ключевое слово span. Я предпочитаю этот подход, так как при работе с многостолбцовым макетом мы обычно представляем блоки с точки зрения количества дорожек сетки, которые они занимают, и корректируем это для разных точек перехода. Чтобы увидеть, как блоки выравниваются по дорожкам, используйте инспектор сетки Firefox. Он наглядно демонстрирует, как размещаются наши элементы.
Существуют некоторые ключевые различия в том, как работает макет сетки по сравнению с системами сеток, которые вы могли использовать ранее. Как вы можете видеть, нам не нужно добавлять никакой разметки для создания строки; системам сеток нужно это сделать, чтобы предотвратить появление элементов в строке выше. С помощью CSS-сетки мы можем помещать элементы в строки без риска их подъёма в строку выше, если она остаётся пустой. Благодаря этому жесткому размещению столбцов и строк мы также можем легко оставить пробелы в нашем макете. Нам также не нужны специальные классы для перемещения или сдвига элементов, для их вдавливания в сетку. Всё, что нам нужно сделать, это указать начальную и конечную линии для элемента.
Создание макета с использованием системы из 12 столбцов
Чтобы увидеть, как работает этот метод макета на практике, мы можем создать тот же макет, что и с grid-template-areas, но на этот раз с использованием 12-столбцовой системы сеток. Начнём с той же разметки, что и в примере с шаблоном областей сетки.
<div class="wrapper">
<header class="main-head">The header</header>
<nav class="main-nav">
<ul>
<li><a href="">Nav 1</a></li>
<li><a href="">Nav 2</a></li>
<li><a href="">Nav 3</a></li>
</ul>
</nav>
<article class="content">
<h1>Main article area</h1>
<p>
In this layout, we display the areas in source order for any screen less
that 500 pixels wide. We go to a two column layout, and then to a three
column layout by redefining the grid, and the placement of items on the
grid.
</p>
</article>
<aside class="side">Sidebar</aside>
<div class="ad">Advertising</div>
<footer class="main-footer">The footer</footer>
</div>
Затем мы можем настроить нашу сетку, как в примере макета с 12 столбцами выше.
.wrapper {
display: grid;
grid-template-columns: repeat(12, [col-start] 1fr);
gap: 20px;
}
Мы снова сделаем это адаптивным макетом, но на этот раз с использованием именованных линий. В каждой точке перехода будет использоваться 12-столбцовая сетка, но количество дорожек, которые будут занимать элементы, меняется в зависимости от размера экрана.
Мы начинаем с мобильной версии, и всё, что мы хотим для самых узких экранов, — это сохранить элементы в исходном порядке и занять всю сетку.
.wrapper > * {
grid-column: col-start / span 12;
}
В следующей точке перехода мы хотим перейти к двухстолбцовому макету. Наш заголовок и навигация по-прежнему занимают всю сетку, поэтому нам не нужно указывать никакого позиционирования для них. Сайдбар начинается с первой столбцовой линии с именем col-start и занимает 3 линии. Он идёт после строчной линии 3, так как заголовок и навигация находятся в первых двух строчных дорожках.
Блок с рекламой расположен под сайдбаром, поэтому начинается со строчной линии сетки 4. Затем у нас есть контент и футер, начинающийся со столбцовой линии col-start 4 и занимающий 9 дорожек, доходя до конца сетки.
@media (min-width: 500px) {
.side {
grid-column: col-start / span 3;
grid-row: 3;
}
.ad {
grid-column: col-start / span 3;
grid-row: 4;
}
.content,
.main-footer {
grid-column: col-start 4 / span 9;
}
nav ul {
display: flex;
justify-content: space-between;
}
}
Наконец, мы переходим к трёхстолбцовой версии этого макета. Заголовок по-прежнему занимает всю сетку, но навигация перемещается вниз, чтобы стать первым сайдбаром, а затем контент и соседний с ним сайдбар. Футер также теперь занимает всю ширину макета.
@media (min-width: 700px) {
.main-nav {
grid-column: col-start / span 2;
grid-row: 2 / 4;
}
.content {
grid-column: col-start 3 / span 8;
grid-row: 2 / 4;
}
.side {
grid-column: col-start 11 / span 2;
grid-row: 2;
}
.ad {
grid-column: col-start 11 / span 2;
grid-row: 3;
}
.main-footer {
grid-column: col-start / span 12;
}
nav ul {
flex-direction: column;
}
}
Ещё раз, инспектор сетки полезен, чтобы увидеть, как сформировался наш макет.
Следует отметить, что при создании этого макета нам не нужно было явно позиционировать каждый элемент в сетке в каждой точке перехода. Мы смогли унаследовать расположение, заданное для предыдущих точек перехода — преимущество работы «сначала с мобильной версией». Мы также можем использовать автоматическое размещение сетки. Соблюдая логический порядок элементов, автоматическое размещение выполняет большую часть работы по размещению элементов в сетке. В заключительном примере этого руководства мы создадим макет, который полностью полагается на автоматическое размещение.
Списки товаров с автоматическим размещением
Многие макеты представляют собой наборы «карт» — списки товаров, галереи изображений и так далее. Сетка может значительно упростить создание таких списков, которые будут адаптивными без необходимости добавлять справочные таблицы стилей для разных устройств. В этом примере я сочетаю макеты CSS сетки и гибкой компоновки, чтобы создать простой макет списка товаров.
Разметка моего списка — это неупорядоченный список элементов. Каждый элемент содержит заголовок, текст различной высоты и ссылку на призыв к действию.
<ul class="listing">
<li>
<h2>Item One</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
<li>
<h2>Item Two</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
<li class="wide">
<h2>Item Three</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
<p>This one has more text than the other items.</p>
<p>Quite a lot more</p>
<p>Perhaps we could do something different with it?</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
<li>
<h2>Item Four</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
<li>
<h2>Item Five</h2>
<div class="body">
<p>The content of this listing item goes here.</p>
</div>
<div class="cta">
<a href="">Call to action!</a>
</div>
</li>
</ul>
Мы создадим сетку с гибким количеством гибких столбцов. Я хочу, чтобы они никогда не становились меньше 200 пикселей, а затем делили оставшееся пространство поровну — так мы всегда получаем столбцы одинаковой ширины. Это достигается функцией minmax() в нашей записи для определения размера дорожек.
.listing {
list-style: none;
margin: 2em;
display: grid;
gap: 20px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
Как только мы добавим этот CSS, элементы начнут выстраиваться в сетку. Если мы уменьшим или увеличим окно, количество дорожек столбцов изменится — без необходимости добавлять точки останова с помощью справочных таблиц стилей и переопределять сетку.
Затем мы можем привести внутренние элементы в порядок, используя немного гибкой компоновки. Я установил элемент списка в display: flex и flex-direction в column. Затем мы можем использовать автоматический отступ в .cta для перемещения этой полосы вниз к нижней части блока.
.listing li {
border: 1px solid #ffe066;
border-radius: 5px;
display: flex;
flex-direction: column;
}
.listing .cta {
margin-top: auto;
border-top: 1px solid #ffe066;
padding: 10px;
text-align: center;
}
.listing .body {
padding: 10px;
}
Это одна из основных причин, по которой кто-то может использовать гибкую компоновку вместо сетки, если нужно только выровнять или распределить что-то в одном измерении, это случай использования гибкой компоновки.
Предотвращение пробелов с помощью ключевого слова dense
Всё это выглядит довольно завершенным, однако иногда у нас есть карточки, содержащие гораздо больше контента, чем другие. Возможно, хотелось бы, чтобы они занимали две дорожки, и тогда они не будут такими высокими. У меня есть класс wide для более крупных элементов, и мы добавляем правило grid-column-end со значением span 2. Теперь, когда сетка встречает этот элемент, она назначит ему две дорожки. В некоторых точках останова это означает, что в сетке образуется пробел — там нет места для размещения элемента, занимающего две дорожки.
Мы можем заполнить эти пробелы, установив grid-auto-flow: dense для контейнера сетки. Однако будьте осторожны, так как это может изменить логический порядок элементов. Вы должны делать это только в том случае, если у ваших элементов нет определенного порядка — и будьте в курсе проблем с порядком табуляции, который следует исходному коду, а не вашему переупорядоченному отображению.
.listing {
list-style: none;
margin: 2em;
display: grid;
gap: 20px;
grid-auto-flow: dense;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.listing .wide {
grid-column-end: span 2;
}
Этот метод использования автоматического размещения с применением правил к определенным элементам очень полезен и может помочь вам работать с контентом, который, например, выводится CMS, где у вас есть повторяющиеся элементы, и вы можете добавить класс к определенным элементам при их отображении в HTML.
Дополнительные возможности изучения
Лучший способ научиться использовать сетку — продолжать создавать примеры, как мы это делали здесь. Выберите что-то, что вы обычно создаёте с помощью своего фреймворка или с помощью плавающих элементов, и посмотрите, сможете ли вы создать это с помощью сетки. Не забудьте найти примеры, которые невозможно создать существующими методами. Это может означать вдохновение журналами или другими источниками, не связанными с веб-сайтами. Сетка открывает возможности, которых у нас раньше не было; нам не нужно придерживаться одних и тех же старых макетов, чтобы её использовать.
- CSS сетка
- CSS Макеты: Сетки
- Полное руководство по CSS сетке на CSS-Tricks (2023)
- Примеры использования сеток
- Примеры макетов веб-сайтов с CSS сеткой на quackit.com
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Realizing_common_layouts_using_grids