Шаблон CSS Grid в действии
С тех пор, как CSS Grid стал поддерживаться в основных браузерах еще в марте 2017 года (почти три года назад), я начал использовать его в своих личных и клиентских проектах, конечно, с подходящим запасным вариантом для не поддерживающих браузеров. Я также сделал инструмент под названием grid-to-flex, который генерирует запасной вариант flexbox для сетки.
Обычный способ добавления сетки
Рассмотрим следующий макет дизайна:
Обычно я устанавливаю grid-column
для каждого элемента заголовка, боковой панели, основного и нижнего колонтитула следующим образом:
.wrapper {
display: grid;
grid-template-columns: 200px 1fr;
grid-gap: 1rem;
}
header {
grid-column: 1 / 3;
}
footer {
grid-column: 1 / 3;
}
Это прекрасно работает, если структура сайта или макет, над которым вы работаете, никогда не изменится. Тем не менее, это не совсем возможно в Интернете. Сеть является гибкой, и, следовательно, макеты, которые мы создаем, должны быть такими.
Например, мы передумали и решили сделать интервал боковой панели до конца страницы, а нижний колонтитул должен иметь такую же ширину, что и основной элемент. Для этого нам нужно изменить значение grid-column
для основного, стороннего и нижнего колонтитулов.
И CSS:
header {
grid-column: 1 / 3;
}
main {
grid-column: 2 / 3;
}
aside {
grid-row: 2 / 4;
}
footer {
grid-column: 2 / 3;
}
Несмотря на то, что я давно работаю с CSS Grid, у нас есть отличные инструменты, которые показывают нам номера линий сетки, такие как Firefox DevTools ниже:
Мне все еще трудно изменить или запомнить количество столбцов и строк для каждого редактирования макета. Может быть, есть лучший визуальный способ для этого, не быть пойманным в цифрах каждый раз, когда требуется редактирование? Да, есть.
Представление областей шаблона сетки
Вместо того, чтобы иметь дело с числами столбцов и строк, есть лучший способ использования grid-template-areas
. Просто он визуально отображает столбцы и строки сетки.
Во-первых, я хочу объяснить концепцию областей в ее простом случае.
.wrapper {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-areas: none | <string>+;
grid-gap: 1rem;
}
Возможное значение для grid-template-areas
- несколько строк, сгруппированных с кавычками. Каждая ячейка в строке представляет столбец, а каждая строка представляет строку в сетке. Мы повторим приведенный выше пример, чтобы понять, как это работает.
.wrapper {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"sidebar footer";
grid-gap: 1rem;
}
header {
grid-area: header;
}
main {
grid-column: main;
}
aside {
grid-row: sidebar;
}
footer {
grid-column: footer;
}
Чтобы понять значение grid-template-areas
, см. иллюстрацию об этом ниже.
Обратите внимание, что представление значения похоже на дизайн макета. Каждый цвет представляет определенный компонент / элемент дизайна.
Так как у нас есть два столбца, 200px
и 1fr
значение grid-template-areas
должно быть приведено в соответствие с ними. Когда я написал «header header», это означает, что ширина заголовка будет 200px + 1fr
, которая фактически равна 100%
ширине родительского элемента.
Пустые районы
Иногда мы хотим, чтобы ячейка в сетке была пустой. Для этого необходимо добавить «точку» внутри определения grid-template-areas
.
.wrapper {
display: grid;
grid-template-columns: 200px 1fr;
grid-template-areas:
". header"
"sidebar main"
"sidebar footer";
grid-gap: 1rem;
}
Помещенная точка означает, что эта ячейка пуста, а голова должна быть помещена во второй столбец. Результат как ниже:
Варианты использования и примеры
Во время обучения я пытался придумать варианты использования, grid-template-areas
которые могут быть полезны. Я надеюсь, что они вам понравятся, и, пожалуйста, не стесняйтесь делиться своими идеями или предложениями, если я что-то пропустил.
1. Избранная статья
У нас есть раздел с избранной статьей, который охватывает высоту двух строк. Для этого нам понадобятся три столбца и две строки. Вот структура HTML:
<main class="wrapper">
<div class="item featured"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</main>
И основной CSS:
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1.25rem;
}
С учетом вышесказанного у нас будет следующая сетка:
Вот как я визуально представляю о grid-template-areas
для этого макета.
Теперь у нас будет две строки для grid-template-areas
. Смотрите ниже CSS:
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas:
"featured item-1 item-1"
"featured item-2 item-2";
grid-gap: 1.25rem;
}
.item.featured {
grid-area: featured;
}
.item-2 {
grid-area: item-1;
}
.item-3 {
grid-area: item-2;
}
Разве это не легко и просто, вместо того, чтобы иметь дело с номерами столбцов и строк?
2. Адаптивный дизайн и сетка.
На основе предыдущего примера мы увидим, как справиться с этим при меньших размерах экрана. Поскольку каждый элемент grid-area
уже применяется к нему, изменение будет только для значения grid-templates-areas
.
В наименьшем размере элементы должны располагаться друг над другом. Затем, если ширина области просмотра больше или равна 600px
, будет запущен макет с 3 столбцами. Наконец, если ширина области просмотра больше или равна 900px
, будет активирована обычная компоновка.
Вот как я добавил области сетки для оболочки:
/* Stacked Layout */
main {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas:
"featured featured featured"
"item-1 item-1 item-1"
"item-2 item-2 item-2";
grid-gap: 1.25rem;
}
/* 3-col Layout */
@media (min-width: 600px) {
main {
grid-template-areas:
"featured item-1 item-2"
"featured item-1 item-2";
}
}
/* Featured Layout */
@media (min-width: 900px) {
main {
grid-template-areas:
"featured item-1 item-1"
"featured item-2 item-2";
}
}
Элементы формы
Хорошим вариантом использования областей сетки являются элементы формы. Допустим, мы хотим, чтобы в форме отображался левый макет для размера мобильного устройства, а правый - для размера рабочего стола.
Для этого я сделаю обертку входной группы в качестве обёртки сетки.
<form>
<p class="input-group">
<label for="">Full Name</label>
<input type="email" name="" id="">
</p>
<!-- Other form elements -->
<p class="input-group">
<button class="c-button">Sign up</button>
</p>
</form>
.input-group {
display: grid;
grid-template-columns: 0.7fr 2fr;
grid-template-areas: "col-1 col-1" "col-2 col-2";
margin-bottom: 1rem;
@media (min-width: 700px) {
grid-template-areas: "col-1 col-2";
}
}
label {
grid-area: col-1;
}
input {
grid-area: col-2;
}
.c-button {
grid-area: col-2;
justify-self: start;
}
Исходя из вышеизложенного, вот как должна выглядеть форма в больших окнах просмотра.
Системы повторного использования и проектирования
Я думал о расширении использования областей сетки, чтобы установить руководящие принципы для дизайн-проекта. Например, раздел с различными вариантами макета.
1. Редакционный макет
Этот редакционный макет является частью системы дизайна. Команда согласилась поработать над двумя вариантами этого макета, добавив или удалив класс CSS. Давайте посмотрим, как работать с первым вариантом с областями сетки.
<div class="c-newspaper">
<article class="c-article c-article--1"></article>
<article class="c-article c-article--2"></article>
<article class="c-article c-article--featured"></article>
<article class="c-article c-article--3"></article>
<article class="c-article c-article--4"></article>
<article class="c-article c-article--5"></article>
<article class="c-article c-article--6"></article>
<article class="c-article c-article--7"></article>
</div>
.c-newspaper {
display: grid;
grid-template-columns: 0.2fr 0.6fr 0.2fr;
grid-template-areas:
"item-1 featured item-2"
"item-3 featured item-4"
"item-5 item-6 item-7";
grid-gap: 1rem;
}
.c-article--1 {
grid-area: item-1;
}
.c-article--2 {
grid-area: item-2;
}
/*..And so on for other elements.. each one has a grid-area..*/
.c-article--7 {
grid-area: item-7;
}
.c-article--featured {
grid-area: featured;
}
Чтобы сделать это более понятным, я представлю область сетки на рисунке ниже.
И для второго варианта я изменил области сетки так, как показано ниже:
.c-newspaper.variation-1 {
grid-template-areas:
"featured featured item-3"
"item-1 item-2 item-4"
"item-5 item-6 item-7";
}
Представьте, распространяется ли эта концепция на различные компоненты и разделы в системе проектирования. В результате будет легко использовать и изменять кодовую базу CSS. Более того, любой, кто использует эту систему проектирования, может создать собственный макет, просто играя со значением grid-template-areas
.
Прогрессивное улучшение
Структура HTML для приведенного выше примера работает, только если поддерживается CSS Grid. Как мы можем использовать flexbox для восстановления и улучшить с помощью Grid? Давайте исследуем это.
Сначала я обернул статьи в три столбца, как показано ниже:
<div class="c-newspaper">
<div class="c-newspaper__column">
<article class="c-article c-article--1"></article>
<article class="c-article c-article--2"></article>
<article class="c-article c-article--featured"></article>
</div>
<div class="c-newspaper__column">
<article class="c-article c-article--3"></article>
<article class="c-article c-article--4"></article>
<article class="c-article c-article--5"></article>
</div>
<div class="c-newspaper__column">
<article class="c-article c-article--6"></article>
<article class="c-article c-article--7"></article>
</div>
</div>
Как только мы получим вышеизложенное, мы можем использовать flexbox для создания макета с тремя столбцами в соответствии с оригинальным дизайном.
.c-newspaper {
display: flex;
flex-wrap: wrap;
}
.c-newspaper__column--1 {
flex: 0 0 20%; /* First Column Takes 20% width */
}
.c-newspaper__column--2 {
flex: 0 0 60%; /* Second Column Takes 60% width */
}
.c-newspaper__column--3 {
flex: 0 0 20%; /* Third Column Takes 20% width */
}
.c-newspaper__item {
margin-bottom: 1rem; /* Spacing below each article */
}
При этом у нас есть макет с 3 колонками, который работает для браузера, который не поддерживает CSS Grid. Следующим шагом является улучшение на основе этого и добавление кода сетки CSS.
Позиционирование каждого элемента сетки по отдельности
Теперь, когда мы завернули статьи в контейнеры из трех столбцов, как расположить каждый элемент сетки по отдельности? Нам нужен способ имитировать идею скрыть контейнеры столбцов и хранить все внутри них. CSS display: contents
на помощь!
Мне нравится это определение в CSS Tricks :
Волшебное новое отображаемое значение, которое по существу делает контейнер исчезающим, делая дочерние элементы дочерними для элемента на следующем уровне в DOM.
@supports (display: contents) {
.c-newspaper__column {
display: contents; /* Each column has disappeared */
}
.c-newspaper {
display: grid;
grid-template-columns: 0.2fr 0.6fr 0.2fr;
grid-template-areas:
"item-1 featured item-2"
"item-3 featured item-4"
"item-5 item-6 item-7";
grid-gap: 1rem;
}
}
Чтобы сделать это более понятным, я сделал ниже GIF, который показывает эффект применения display: contents
к каждому из контейнеров .c-newspaper__column
.
Медиа компонент
Медиа компонент является хорошим примером использования областей сетки. Допустим, мы хотим переключить размещение медиа и контента. Сетка идеально подходит для этого.
.c-media {
display: grid;
grid-template-areas: "thumb content";
grid-gap: 1rem;
}
.c-media.flipped {
grid-template-areas: "content thumb";
}
.c-media__thumb {
grid-area: thumb;
}
.c-media__content {
grid-area: content;
}
Отладочная сетка
Мой любимый браузер для работы с сеткой CSS - Firefox. Его DevTools имеет несколько отличных опций для отладки CSS. Например, он показывает имена областей сетки, и даже показывает небольшое представление значения grid-template-areas
в правом нижнем углу.