Учимся верстать в сетке: большой гайд по CSS Grid
Знакомимся с самой гибкой и современной разметкой CSS.
Иллюстрация: Оля Ежак для Skillbox Media
При просмотре разных сайтов в интернете можно заметить, как аккуратно располагаются на них элементы независимо от размера экрана: навигация, кнопки, блоки с текстом и другие вещи. За это отвечает язык разметки CSS (Cascading Style Sheets). Она бывает разных видов, но сегодня поговорим об одном из них, самом адаптивном — CSS-гридах.
Из этой статьи вы узнаете:
- Что такое CSS Grid
- Как его создать
- Какие свойства есть у грид-контейнера
- А какие — у грид-элементов
- Как задать отступы между элементами
- Как выровнять сразу все элементы в грид-контейнере
- Как выровнять отдельные элементы
- Что такое вложенные гриды
- Что нужно запомнить
Что такое CSS Grid
Grid (сетка) — это вид разметки, в котором элементы на сайте расположены в виде таблицы. Главная фишка этой таблицы в гибкости — можно объединять отдельные ячейки, менять размеры строк и столбцов, регулировать отступы между ними. А ещё гриды хорошо приспосабливаются к разным размерам экрана, что делает их адаптивными.
Структура грида напоминает обычный Excel-файл: есть горизонтальные и вертикальные линии, которые вместе образуют много разных ячеек. Только, в отличие от файла в Excel, внутри ячеек находятся не выгрузки по зарплате за март, а элементы сайта: текст, картинки, кнопки, блоки HTML-кода и так далее. А формально все эти части грид-разметки называются так:
- grid-контейнер — самый главный элемент во всей разметке, в нём хранится всё содержимое сетки;
- grid-ячейка — единица грид-сетки, сюда можно положить один или несколько блоков кода;
- grid-линия — горизонтальная или вертикальная линия, разделяющая столбцы и колонки;
- grid-строка (row) — ряд ячеек;
- grid-столбец (column) — колонка ячеек;
- grid-элемент — какой-либо элемент сайта;
- grid-область (area) — пространство из ячеек, в CSS можно объединить несколько ячеек в одну и работать с ними как с единым целым.
А вот как они располагаются на схеме:
В отличие от Flexbox — другого популярного вида CSS-разметки — Grid позволяет создавать двумерные таблицы. Это значит, что в них могут быть одновременно и ряды, и колонки. А во Flexbox всё строго: можно выстроить элементы или в столбик, или в линию — сочетать оба метода нельзя.
За дело: создаём наш первый Grid
Чтобы опробовать Grid в деле, нам понадобится два файла: HTML и CSS. Начнём со «скелета» — создадим HTML-файл вот с таким содержимым (для удобства это можно сделать в онлайн-редакторе):
Здесь мы задали несколько простых объектов — обычные латинские буквы A, B, C, D и E — и расположили их на отдельных строчках.
Теперь настало время объявить саму сетку. Для этого в той же папке создадим файл style.css и поместим туда вот такой код:
Пока что ничего не изменилось — чтобы нашу сетку было видно, добавим ей стили: контейнер обведём зелёным цветом, а все элементы внутри него — чёрной штрих-пунктирной линией.
Должно получиться примерно так:
Уже лучше! Но пока наши элементы расположены по дефолту и какой-то гибкой вёрсткой тут и не пахнет. Чтобы научиться настраивать сетку под себя, разберёмся со свойствами гридов.
Свойства грид-контейнера
Свойства грид-контейнера задают параметры таблицы — количество строк и столбцов, их размеры, расположение в сетке и другие.
Колонки (grid-template-columns)
Чтобы создать колонки, нужно просто записать их размеры через пробел. Размеры можно указывать в разных единицах измерения: пикселях, процентах, сантиметрах и так далее. Причём можно смешивать несколько единиц в пределах одного свойства.
Допустим, нам нужно создать три колонки: первая занимает одну треть экрана, вторая — ровно 100px, а третья — всё оставшееся место. Самый очевидный вариант — записать через проценты:
Но тогда общая ширина всех колонок превысит 100%, и третья колонка уедет за пределы контейнера:
Чтобы избегать таких ситуаций, гридам придумали новую единицу измерения — фракцию (fr). Она позволяет разделить свободное пространство экрана на несколько частей и не возиться с ручной подгонкой процентов.
А нам того и надо — первому столбцу отдаём одну часть свободного пространства (1fr), третьему — две (2fr), а тот, что посередине, пускай забирает свои 100px:
И вот какая получается красота — всё аккуратно и в рамочке:
Ряды (grid-template-rows)
Едем дальше. Захотели мы, допустим, задать нашей табличке размеры строк:
Но вдруг видим, что размеры двух строчек повторяются — они занимают ровно 2fr. Чтобы не писать дважды одно и то же, поместим их в функцию repeat. Она принимает на вход два параметра — размер строки во фракциях и количество его повторений:
И полная, и краткая запись уместны — их можно чередовать в зависимости от контекста. Например, в нашем случае без функции можно было бы обойтись — но если надо создать, допустим, 10 колонок, она помогла бы сделать код более лаконичным и читаемым.
Вот как работает функция repeat наглядно:
Обратите внимание: высоту последней строчки E мы нигде не указывали, поэтому она остаётся дефолтной.
Области (grid-template-areas)
Одна из особенностей грид-разметки — возможность создавать области и гибко регулировать их размеры.
Чтобы создать область, объявим для каждого элемента в CSS-файле свойство grid-area — его параметром будет любое имя, какое захотите. Можно просто добавить в любое место CSS-файла этот код:
Затем в грид-контейнере создаём «матрицу» из этих имён:
Вуаля! Наши элементы выстроились по шаблону:
Как это работает. Каждое имя в grid-template-areas соответствует определённому объекту. Одинаковые имена, стоящие рядом, собирают несколько ячеек в единое целое — то есть в грид-область:
- Элемент A с «псевдонимом» f занимает область в 25 ячеек.
- Элемент B (i) — в 9 ячеек.
- Элемент C (b) — в 4 ячейки.
- Элемент D (o) — в 1 ячейку.
- Элемент E (n) — тоже в 1 ячейку.
Сокращённое свойство (grid-template)
Свойство grid-template позволяет в краткой форме определить или столбцы со строками, или целые области.
1. Короткая форма для грид-строк и грид-колонок:
Фишка в том, что мы всего одной строчкой создаём целую таблицу — просто записываем через слеш количество рядов и столбцов. Для примера создадим сетку из трёх строк по 1fr и двух столбцов по 2fr.
Кстати, свойство grid-template тоже принимает функцию repeat.
И, как видите, результат остаётся неизменным:
2. Короткая форма для грид-областей.
Также сокращённая запись поддерживает объявление грид-областей, нужно только объявить свойство grid-area для каждого объекта:
Профит:
Свойства грид-элементов
С помощью этих свойств можно прямо указать браузеру, где должны находиться элементы. Для этого нужно указать две точки: с какой линии элемент начинается и какой заканчивается — это работает как по горизонтали, так и по вертикали.
Вот так можно двигать элемент по горизонтали:
Задаёт начальную позицию (линию) столбцов
Задаёт конечную позицию (линию) столбцов
Объединённое свойство грид-линий столбцов: начало и конец
А вот так — по вертикали:
Задаёт начальную позицию (линию) строк
Задаёт конечную позицию (линию) строк
Объединённое свойство грид-линий строк: начало и конец
Но есть и одно общее свойство, объединяющее все четыре основных:
Теперь давайте попробуем задать эти свойства первым трём элементам из нашей конструкции с буквами:
Этот код указывает нашим буквам, какие позиции занять в сетке:
- Элемент А занял область от первой до четвёртой линии — и по горизонтали, и по вертикали.
- Элемент B занял область от четвёртой до шестой линии по горизонтали и от первой до третьей по вертикали.
- Элемент С занял область от четвёртой до пятой линии по горизонтали и от третьей до четвёртой линии по вертикали.
- Ну а остальные расположились по дефолту :)
Выглядит так:
Grid-gap (отступы)
Используя grid-gap, можно регулировать интервалы между элементами в контейнере. Делается это с помощью двух параметров:
- column-gap — расстояние между колонками;
- row-gap — расстояние между строками.
Вот как это выглядит в коде:
Как и у grid-template, у gap есть сокращённая запись, где параметры column-gap и row-gap можно записать через пробел:
Выравнивание грид-контейнера
Со свойствами элементов разобрались, теперь поговорим о том, как их выровнять в рамках контейнера или области.
justify-items
Что делает: выравнивает элементы в пределах области по горизонтали.
Растягивает элементы на всю ширину грид-ячейки
Располагает элементы в левой части грид-ячейки или области
Располагает элементы в центре грид-ячейки или области
Располагает элементы в правой части грид-ячейки или области
align-items
Что делает: выравнивает элементы в пределах области по вертикали.
Растягивает элементы на всю длину грид-ячейки
Располагает элементы в верхней части грид-ячейки
Располагает элементы в центре грид-ячейки
Располагает элементы в нижней части грид-ячейки
justify-content
Что делает: выравнивает элементы в пределах всего контейнера по горизонтали.
Располагает элементы в левой части грид-контейнера
Располагает элементы по центру грид-контейнера
Располагает все элементы в правой части грид-контейнера
Распределяет элементы по левому и правому краю. Первый элемент располагается ближе к началу, а последний — ближе к концу
Распределение с равным пространством между элементами и половиной этого пространства от краёв
Распределение с равным пространством и между элементами, и от краёв
align-content
Что делает: выравнивает элементы в пределах всего контейнера по вертикали.
Для начала увеличим высоту контейнера с помощью параметра height:
Пока элементы просто растянулись по длине контейнера, а теперь попробуем применить к нему следующие свойства:
Все элементы расположились в верхней части контейнера
Все элементы расположились в середине грид-контейнера
Элементы расположились по верхнему и нижнему краю. Первый элемент ближе к началу, последний — ближе к концу
Распределение с равным пространством между элементами и половиной этого пространства от краёв
Выравнивание грид-элементов
Следующие свойства работают с отдельными грид-элементами, поэтому параметры мы будем прописывать не всему контейнеру, а элементу — скажем, с буквой A.
justify-self
Что делает: выравнивает грид-элементы по горизонтали.
Элемент A растянулся по всей длине грид-области
Элемент A расположился в центре грид-области
Элемент A расположился в начале грид-области
Элемент A расположился в конце грид-области
align-self
Что делает: выравнивает грид-элементы по вертикали.
Элемент A растянулся по всей ширине грид-области
Элемент A расположился в середине грид-области
Элемент A расположился в начале грид-области
Элемент A расположился в конце грид-области
Грид в гриде: вложенные гриды
В CSS грид бывает вложенным — это значит, что он содержит в себе другой грид-контейнер. Чтобы понять, как это работает, давайте немного пересоберём наш HTML-каркас, добавив в него ещё один подуровень элементов:
Для основного контейнера в CSS-файле создадим сетку 3 на 3:
И вот какая матрёшка у нас получилась:
А теперь для элемента D определим display: grid — то есть объявим внутри него ещё одну сетку. Для свойств строк и столбцов напишем параметр subgrid, который заимствует параметры родительского грида:
Готово! Теперь можно мастерски жонглировать элементами E, F, G, задавая им разное расположение в пределах элемента D (который тоже стал сеткой). Например, сделаем так, чтобы E начинался от второй вертикальной линии грида до третьей:
Внутренние элементы, в свою очередь, расположились уже во вложенном гриде:
Что нужно запомнить
Сегодня мы узнали, что такое грид в CSS: как он работает, из чего состоит и как настраивается. Повторим ключевые моменты:
- Grid Layout в CSS — это гибкая разметка, при которой элементы располагаются в виде таблицы. Таблица состоит из ячеек, которые можно собирать в целые области.
- Чтобы создать грид, нужно в файле с CSS-разметкой добавить строчку display: grid.
- Грид состоит из родительского контейнера и вложенных в него элементов. Элементы могут занимать несколько ячеек, которые складываются в столбцы, колонки или области.
- Фракция — единица измерения в CSS, созданная для удобства — чтобы можно было задавать соотношения между элементами и не подгонять вручную проценты.
- Грид может содержать в себе другой грид — такая конструкция называется вложенным subgrid.
- Основными свойствами грид-контейнера являются: grid-template, grid-template-columns, grid-template-rows, grid-template-areas. Они позволяют задавать размеры колонок, строк или целых областей.
- За отступы между колонками грида отвечает свойство column-gap, а между рядами — row-gap.
- Горизонтально выровнять элементы контейнера можно с помощью justify-items и justify-content, а вертикально — с align-items и align-content.
- Настроить расположение элементов от определённой линии грид-сетки можно с помощью свойств:
- по горизонтальной оси: grid-column-start, grid-column-end, grid-column;
- по вертикальной оси: grid-row-start, grid-row-end, grid-row;
- или общим свойством grid-area.
- Выровнять конкретный элемент грида можно с помощью justify-self (по горизонтали) и align-self (по вертикали).
Больше интересного про код в нашем телеграм-канале. Подписывайтесь!