Время на прочтение
7 мин
Количество просмотров 254K
Сегодня мы с вами рассмотрим свойства CSS Grid
(далее также — Грид), позволяющие создавать адаптивные или отзывчивые макеты веб-страниц. Я постараюсь кратко, но полно объяснить, как работает каждое свойство.
Что такое CSS Grid
?
Грид — это макет для сайта (его схема, проект).
Грид-модель позволяет размещать контент сайта (располагать его определенным образом, позиционировать). Она позволяет создавать структуры, необходимые для обеспечения отзывчивости сайтов на различных устройствах. Это означает, что сайт будет одинаково хорошо смотреться на компьютере, телефоне и планшете.
Вот простой пример макета сайта, созданного с помощью Грида.
Компьютер
Телефон
Архитектура CSS Grid
Как же Грид работает? Элементы Грида (grid items) располагаются вдоль главной или основной (main) и поперечной (cross) оси (axis). При помощи различных свойств мы можем манипулировать элементами для создания макетов.
Помимо прочего, у нас имеется возможность объединять строки и колонки подобно тому, как мы это делаем в Excel
, что предоставляет нам большую гибкость, чем Флекс (Flexbox
).
К слову, если вас интересует Флекс, вот соответствующая статья.
Схема CSS Grid
Схема содержит все возможные свойства, предоставляемые Гридом. Эти свойства делятся на:
- родительские (свойства грид-контейнера) и
- дочерние (свойства грид-элементов)
Обратите внимание: красным цветом отмечены сокращения для свойств:
К концу настоящей статьи у вас будет полное понимание того, как работает каждое из них.
Настройка проекта
Для данного проекта требуются начальные знания HTML
, CSS
и умение работать с VSCode
(или другим редактором по вашему вкусу). Делаем следующее:
- Создаем директорию для проекта, например,
Project1
и открываем ее в редакторе (cd Project1
,code .
) - Создаем файлы
index.html
иstyle.css
- Устанавливаем в
VSCode
сервер для разработки (Live Server
, расширение) и запускаем его
Или вы можете просто открыть Codepen
(или любую другую песочницу) и начать писать код.
Все готово, можно приступать к делу.
HTML
Создаем 3 контейнера внутри body
:
<div class="container">
<div class="box-1"> A </div>
<div class="box-2"> B </div>
<div class="box-3"> C </div>
</div>
CSS
Шаг 1
Сбрасываем стили:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
Шаг 2
Немного стилизуем body
:
body {
font-family: sans-serif;
font-size: 40px;
width: 100%;
min-height: 100vh;
}
Шаг 3
Стилизуем все контейнеры:
[class^="box-"] {
background-color: skyblue;
/* Размещаем контейнеры по центру */
display: grid;
place-items: center;
}
Не волнуйтесь, мы рассмотрим каждое из указанных свойств Грида.
Шаг 4
Добавим небольшой отступ между контейнерами:
.container {
display: grid;
gap: 20px;
}
Погодите-ка
Давайте разберемся с отношениями между родительским и дочерними элементами.
Свойства родительского элемента определяются в .container
, а свойства дочерних элементов — в .box-*
.
Свойства грид-контейнера
Начнем со свойств родительского элемента.
grid-template-columns
Данное свойство используется для определения количества и ширины колонок. При этом, можно определять как свойства для каждой колонки в отдельности, так и устанавливать ширину всех колонок с помощью функции repeat()
.
Добавим строку в style.css
:
.container {
display: grid;
gap: 20px;
/* ! */
grid-template-columns: 200px auto 100px;
}
Обратите внимание:
- значения в пикселях будут точными. Ключевое слово
auto
означает заполнение элементом всего доступного пространства - использование единицы
fr
(фракция) вrepeat()
означает, что все контейнеры будут иметь одинаковую ширину
grid-template-rows
Данное свойство используется для определения количества и высоты строк. При этом, можно определять как высоту каждой колонки в отдельности, так и устанавливать высоту всех строк с помощью функции repeat()
.
Изменим строку в style.css
:
.container {
display: grid;
gap: 20px;
height: 100vh;
/* ! */
grid-template-rows: 200px auto 100px;
}
grid-template-areas
Данное свойство используется для определения количества пространства, занимаемого ячейкой Грида (grid cell), в терминах колонок и строк, в родительском контейнере.
Это можно считать схемой макета:
Для получения результата требуется не только родительское, но и хотя бы одно дочернее свойство:
grid-template-areas
: родительское свойство, создающее схемуgrid-area
: дочернее свойство, которое использует схему
Создаем схему
.container {
display: grid;
gap: 20px;
height: 100vh;
/* ! */
grid-template-areas:
"A A A A A A A A A A A A"
"B B B B B B B B B B C C"
"B B B B B B B B B B C C";
}
Применяем схему
.box-1 {
grid-area: A;
}
.box-2 {
grid-area: B;
}
.box-3 {
grid-area: C;
}
Обратите внимание: мы вернемся к свойству grid-area
, когда будем говорить о дочерних свойствах.
column-gap
Данное свойство используется для добавления отступа между колонками.
style.css
:
.container {
display: grid;
height: 100vh;
grid-template-columns: 100px 100px 100px;
/* ! */
column-gap: 50px;
}
Обратите внимание: свойство column-gap
используется совместно со свойством grid-template-columns
.
row-gap
Данное свойство используется для добавления отступов между строками.
style.css
:
.container {
display: grid;
height: 100vh;
grid-template-rows: 100px 100px 100px;
/* ! */
row-gap: 50px;
}
Обратите внимание: свойство row-gap
используется совместно со свойством grid-template-rows
.
justify-items
Данное свойство используется для позиционирования грид-элементов внутри грид-контейнера вдоль главной оси. Оно принимает 4 возможных значения:
Добавим еще один контейнер в HTML
:
<div class="container">
<!-- Здесь находятся контейнеры A, B, C -->
<div class="box-4"> D </div>
</div
И немного изменим CSS
:
.container {
display: grid;
gap: 50px;
height: 100vh;
/* Каждый контейнер имеет размер 200px на 200px */
grid-template-rows: 200px 200px;
grid-template-columns: 200px 200px;
/* ! */
justify-items : end;
}
align-items
Данное свойство используется для позиционирования грид-элементов внутри грид-контейера вдоль поперечной оси. Оно принимает 4 возможных значения:
style.css
:
.container {
display: grid;
gap: 50px;
height: 100vh;
grid-template-rows: 200px 200px;
grid-template-columns: 200px 200px;
/* ! */
align-items: center;
}
justify-content
Данное свойство используется для позиционирования самого грида внутри грид-контейнера вдоль основной оси. Оно принимает 7 возможных значений:
style.css
:
.container {
display: grid;
gap: 50px;
height: 100vh;
grid-template-rows: 200px 200px;
grid-template-columns: 200px 200px;
/* ! */
justify-content: center;
}
align-content
Данное свойство используется для позиционирования самого грида внутри грид-контейнера вдоль поперечной оси. Оно принимает 7 возможных значений:
style.css
:
.container {
display: grid;
gap: 50px;
height: 100vh;
grid-template-rows: 200px 200px;
grid-template-columns: 200px 200px;
/* ! */
align-content : center;
}
Свойства грид-элементов
Шкала CSS Grid
Данная шкала показывает, как вычисляются строки и колонки при их объединении. Для этого используется два вида единиц:
- целые числа (1, 2, 3 и т.д.)
- ключевое слово
span
На представленной ниже иллюстрации показаны начальные и конечные точки строк и колонок в одной ячейке:
index.html
:
<div class="container">
<div class="box-1"> A </div>
<div class="box-2"> B </div>
<div class="box-3"> C </div>
<div class="box-4"> D </div>
</div>
При использовании функции repeat()
мы может установить одинаковую ширину/высоту для колонок/строк. Пример с колонками:
grid-template-columns : repeat(4, 1fr);
Это аналогично следующему:
grid-template-columns : 1fr 1fr 1fr 1fr;
Небольшая заметка
При использовании единицы измерения fr
, доступное пространство делится на равные части.
grid-template-columns : repeat(4, 1fr);
В данном случае доступное пространство делится на 4 равные части.
Продолжаем веселиться!
grid-columns: start/end
Данное свойство позволяет объединять колонки. Оно является сокращением для:
grid-column-start
grid-column-end
style.css
:
.container {
display: grid;
gap: 20px;
height: 100vh;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: repeat(12, 1fr);
}
Результат:
Мы разделили доступное пространство на 12 равных частей как по ширине, так и по высоте. 1 контейнер занимает 1 часть или фракцию. В данном случае 8 фракций остались невостребованными.
Поскольку мы говорим о свойствах дочерних элементов, имеет смысл разделить их стили:
.box-1 {}
.box-2 {}
.box-3 {}
.box-4 {}
Вернемся к шкале. Мы разбираемся с колонками — поэтому пока не обращайте внимания на строки.
Каждый класс .box-*
по умолчанию имеет такой масштаб (scale):
grid-column-start: 1;
grid-column-end: 2;
/* Сокращение */
grid-column: 1 / 2
Это можно переписать с помощью ключевого слова span
:
grid-column : span 1;
Давайте «присвоим» 8 фракций .box-1
:
.box-1 {
grid-column: 1 / 10
}
Результат:
Небольшая заметка
Как мы производим вычисления? box-1
занимает 1 часть. Кроме этого, к ней добавляется еще 8 частей. И еще 1 в конце. Получается: 8 + 1 + 1 = 10.
Как использовать ключевое слово span
Считается, что использование span
делает код более читаемым.
В этом случае нам просто нужно добавить к box-1
8 частей:
.box-1 {
grid-column: span 9;
}
Это даст такой же результат.
grid-row: start/end
Данное свойство позволяет объединять строки. Оно является сокращением для:
grid-row-start
grid-row-end
Теперь сосредоточимся на строках:
Давайте добавим к box-1
9 частей:
.box-1 {
grid-row : 1 / 11;
}
Расчет выглядит так: box-1
занимает 1 часть + 9 частей + 1 часть в конце, получается 9 + 1 + 1 = 11.
Вот вариант со span
:
.box-1 {
grid-row: span 10;
}
Результат:
grid-area
Сначала нам нужно настроить grid-temlate-areas
, о чем мы говорили выше. После этого в дочерних классах определяются названия областей, которые используются в родительском классе:
Определяем grid-template-areas
в родительском классе:
style.css
:
.container {
display: grid;
gap: 20px;
height: 100vh;
grid-template-areas:
"A A A A A A A A A A A A"
"B B B B B B B B B B C C"
"B B B B B B B B B B C C";
}
Затем определяем grid-area
в дочерних классах:
style.css
:
.box-1 {
grid-area: A;
}
.box-2 {
grid-area: B;
}
.box-3 {
grid-area: C;
}
justify-self
Данное свойство используется для позиционирования отдельного грид-элемента вдоль основной оси. Оно принимает 4 возможных значения:
style.css
:
.container {
display: grid;
gap :25px;
height: 100vh;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
.box-1 {
/* ! */
justify-self : start;
}
align-self
Данное свойство используется для позиционирования отдельного грид-элемента вдоль поперечной оси. Оно принимает 4 возможных значения:
style.css
:
.container {
display: grid;
gap :25px;
height: 100vh;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
.box-1 {
/* ! */
align-self : start;
}
Сокращения для свойств CSS Grid
place-content
place-items
place-self
grid-template
gap
/grid-gap
place-content
Данное свойство является сокращением для:
align-content
justify-content
Пример:
align-content: center;
justify-content: end;
/* ! */
place-content: center / end;
place-items
Данное свойство является сокращением для:
align-items
justify-items
Пример:
align-items: end;
justify-items: center;
/* ! */
place-items: end / center;
place-self
Данное свойство является сокращением для:
align-self
justify-self
Пример:
align-self: start;
justify-self: end;
/* ! */
place-self: start / end;
grid-template
Данное свойство является сокращением для:
grid-template-rows
grid-template-columns
Пример:
grid-template-rows: 100px 100px;
grid-template-columns: 200px 200px;
/* ! */
grid-template: 100px 100px / 200px 200px;
gap/grid-gap
Данное свойство является сокращением для:
row-gap
columns-gap
Пример:
row-gap: 20px ;
column-gap: 30px ;
/* ! */
gap: 20px 30px;
Заключение
Теперь в ваших руках имеется мощное средство для создания адаптивных макетов веб-страниц.
VPS-хостинг с быстрыми NVMе-дисками и посуточной оплатой. Загрузка своего ISO.
#статьи
- 13 мар 2023
-
0
Знакомимся с самой гибкой и современной разметкой CSS.
Иллюстрация: Оля Ежак для Skillbox Media
Программист, музыкант. Знает Java, C# и Unity3D, но не собирается останавливаться на достигнутом.
При просмотре разных сайтов в интернете можно заметить, как аккуратно располагаются на них элементы независимо от размера экрана: навигация, кнопки, блоки с текстом и другие вещи. За это отвечает язык разметки CSS (Cascading Style Sheets). Она бывает разных видов, но сегодня поговорим об одном из них, самом адаптивном — CSS-гридах.
Из этой статьи вы узнаете:
- Что такое CSS Grid
- Как его создать
- Какие свойства есть у грид-контейнера
- А какие — у грид-элементов
- Как задать отступы между элементами
- Как выровнять сразу все элементы в грид-контейнере
- Как выровнять отдельные элементы
- Что такое вложенные гриды
- Что нужно запомнить
Grid (сетка) — это вид разметки, в котором элементы на сайте расположены в виде таблицы. Главная фишка этой таблицы в гибкости — можно объединять отдельные ячейки, менять размеры строк и столбцов, регулировать отступы между ними. А ещё гриды хорошо приспосабливаются к разным размерам экрана, что делает их адаптивными.
Структура грида напоминает обычный Excel-файл: есть горизонтальные и вертикальные линии, которые вместе образуют много разных ячеек. Только, в отличие от файла в Excel, внутри ячеек находятся не выгрузки по зарплате за март, а элементы сайта: текст, картинки, кнопки, блоки HTML-кода и так далее. А формально все эти части грид-разметки называются так:
- grid-контейнер — самый главный элемент во всей разметке, в нём хранится всё содержимое сетки;
- grid-ячейка — единица грид-сетки, сюда можно положить один или несколько блоков кода;
- grid-линия — горизонтальная или вертикальная линия, разделяющая столбцы и колонки;
- grid-строка (row) — ряд ячеек;
- grid-столбец (column) — колонка ячеек;
- grid-элемент — какой-либо элемент сайта;
- grid-область (area) — пространство из ячеек, в CSS можно объединить несколько ячеек в одну и работать с ними как с единым целым.
А вот как они располагаются на схеме:
В отличие от Flexbox — другого популярного вида CSS-разметки — Grid позволяет создавать двумерные таблицы. Это значит, что в них могут быть одновременно и ряды, и колонки. А во Flexbox всё строго: можно выстроить элементы или в столбик, или в линию — сочетать оба метода нельзя.
Чтобы опробовать Grid в деле, нам понадобится два файла: HTML и CSS. Начнём со «скелета» — создадим HTML-файл вот с таким содержимым (для удобства это можно сделать в онлайн-редакторе):
<head> <title>CSS Grid Layout</title> <link rel="stylesheet" href="style.css"> </head> <body> <!-- Это будет грид-контейнер с пятью элементами внутри --> <div class="container"> <div class="A">A</div> <div class="B">B</div> <div class="C">C</div> <div class="D">D</div> <div class="E">E</div> </div> </body>
Здесь мы задали несколько простых объектов — обычные латинские буквы A, B, C, D и E — и расположили их на отдельных строчках.
Теперь настало время объявить саму сетку. Для этого в той же папке создадим файл style.css и поместим туда вот такой код:
/* Объявляем grid-контейнер */ .container { /* Задаём свойства элементов HTML-класса «контейнер» */ display: grid; /* Режим отображения меняем на «сетку» */ }
Пока что ничего не изменилось — чтобы нашу сетку было видно, добавим ей стили: контейнер обведём зелёным цветом, а все элементы внутри него — чёрной штрих-пунктирной линией.
/* Добавляем оформление grid-контейнеру: */ .container { border: 2px solid rgb(80, 145, 27); /* Обводим зелёной линией */ border-radius: 5px; /* Скругляем углы на 5 пикселей */ } /* Добавляем оформление элементам grid-контейнера: */ .container * { border: 1px dashed; /* Обводим чёрным пунктиром */ border-radius: 10px; /* Скругляем углы на 10 пикселей */ background-color: rgba(82, 29, 179, 0.5); /* Фон красим фиолетовым */ text-align: center; /* Контент размещаем в центре по горизонтали */ } /* Для разделения действий мы несколько раз объявили один и тот же элемент .container. На самом деле все эти блоки — единое целое, и относятся к одному классу — container. */
Должно получиться примерно так:
Уже лучше! Но пока наши элементы расположены по дефолту и какой-то гибкой вёрсткой тут и не пахнет. Чтобы научиться настраивать сетку под себя, разберёмся со свойствами гридов.
Свойства грид-контейнера задают параметры таблицы — количество строк и столбцов, их размеры, расположение в сетке и другие.
Чтобы создать колонки, нужно просто записать их размеры через пробел. Размеры можно указывать в разных единицах измерения: пикселях, процентах, сантиметрах и так далее. Причём можно смешивать несколько единиц в пределах одного свойства.
Допустим, нам нужно создать три колонки: первая занимает одну треть экрана, вторая — ровно 100px, а третья — всё оставшееся место. Самый очевидный вариант — записать через проценты:
.container { display: grid; grid-template-columns: 30% 100px 70%; }
Но тогда общая ширина всех колонок превысит 100%, и третья колонка уедет за пределы контейнера:
Чтобы избегать таких ситуаций, гридам придумали новую единицу измерения — фракцию (fr). Она позволяет разделить свободное пространство экрана на несколько частей и не возиться с ручной подгонкой процентов.
А нам того и надо — первому столбцу отдаём одну часть свободного пространства (1fr), третьему — две (2fr), а тот, что посередине, пускай забирает свои 100px:
.container { display: grid; grid-template-columns: 1fr 100px 2fr; }
И вот какая получается красота — всё аккуратно и в рамочке:
Едем дальше. Захотели мы, допустим, задать нашей табличке размеры строк:
.container { display: grid; grid-template-rows: 3fr 2fr 2fr 1fr; }
Но вдруг видим, что размеры двух строчек повторяются — они занимают ровно 2fr. Чтобы не писать дважды одно и то же, поместим их в функцию repeat. Она принимает на вход два параметра — размер строки во фракциях и количество его повторений:
grid-template-rows: 3fr repeat(2, 2fr) 1fr;
И полная, и краткая запись уместны — их можно чередовать в зависимости от контекста. Например, в нашем случае без функции можно было бы обойтись — но если надо создать, допустим, 10 колонок, она помогла бы сделать код более лаконичным и читаемым.
Вот как работает функция repeat наглядно:
Обратите внимание: высоту последней строчки E мы нигде не указывали, поэтому она остаётся дефолтной.
Одна из особенностей грид-разметки — возможность создавать области и гибко регулировать их размеры.
Чтобы создать область, объявим для каждого элемента в CSS-файле свойство grid-area — его параметром будет любое имя, какое захотите. Можно просто добавить в любое место CSS-файла этот код:
.A { grid-area: f; } .B { grid-area: i; } .C { grid-area: b; } .D { grid-area: o; } .E { grid-area: n; }
Затем в грид-контейнере создаём «матрицу» из этих имён:
.container { display: grid; grid-template-areas: "f f f f f i i i" "f f f f f i i i" "f f f f f i i i" "f f f f f o b b" "f f f f f n b b"; }
Вуаля! Наши элементы выстроились по шаблону:
Как это работает. Каждое имя в grid-template-areas соответствует определённому объекту. Одинаковые имена, стоящие рядом, собирают несколько ячеек в единое целое — то есть в грид-область:
- Элемент A с «псевдонимом» f занимает область в 25 ячеек.
- Элемент B (i) — в 9 ячеек.
- Элемент C (b) — в 4 ячейки.
- Элемент D (o) — в 1 ячейку.
- Элемент E (n) — тоже в 1 ячейку.
Свойство grid-template позволяет в краткой форме определить или столбцы со строками, или целые области.
1. Короткая форма для грид-строк и грид-колонок:
/* Сетка из строк и столбцов */ grid-template: grid-template-rows / grid-template-columns;
Фишка в том, что мы всего одной строчкой создаём целую таблицу — просто записываем через слеш количество рядов и столбцов. Для примера создадим сетку из трёх строк по 1fr и двух столбцов по 2fr.
.container{ display: grid; grid-template: 1fr 1fr 1fr / 2fr 2fr; }
Кстати, свойство grid-template тоже принимает функцию repeat.
.container{ display: grid; grid-template: repeat(3, 1fr) / repeat(2, 2fr); }
И, как видите, результат остаётся неизменным:
2. Короткая форма для грид-областей.
Также сокращённая запись поддерживает объявление грид-областей, нужно только объявить свойство grid-area для каждого объекта:
.container { display: grid; grid-template: "f f f i i" "f f f i i" "f f f b o" ". . n n n"; } .A { grid-area: f; } .B { grid-area: i; } .C { grid-area: b; } .D { grid-area: o; } .E { grid-area: n; }
Профит:
С помощью этих свойств можно прямо указать браузеру, где должны находиться элементы. Для этого нужно указать две точки: с какой линии элемент начинается и какой заканчивается — это работает как по горизонтали, так и по вертикали.
Вот так можно двигать элемент по горизонтали:
Задаёт начальную позицию (линию) столбцов
Задаёт конечную позицию (линию) столбцов
grid-column: grid-column-start / grid-column-end;
Объединённое свойство грид-линий столбцов: начало и конец
А вот так — по вертикали:
Задаёт начальную позицию (линию) строк
Задаёт конечную позицию (линию) строк
grid-row: grid-row-start / grid-row-end;
Объединённое свойство грид-линий строк: начало и конец
Но есть и одно общее свойство, объединяющее все четыре основных:
grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end;
Теперь давайте попробуем задать эти свойства первым трём элементам из нашей конструкции с буквами:
/* Объявляем грид 5 × 3 */ .container { display: grid; grid-template: repeat(3, 1fr) / repeat(5, 1fr) ; } /* Расставляем первые три элемента: A, B и C */ .A { grid-area: 1 / 1 / 4 / 4; } .B { grid-column-start: 4; grid-column-end: 6; grid-row-start: 1; grid-row-end: 3; } .C { grid-column: 4 / 5; grid-row: 3 / 4; }
Этот код указывает нашим буквам, какие позиции занять в сетке:
- Элемент А занял область от первой до четвёртой линии — и по горизонтали, и по вертикали.
- Элемент B занял область от четвёртой до шестой линии по горизонтали и от первой до третьей по вертикали.
- Элемент С занял область от четвёртой до пятой линии по горизонтали и от третьей до четвёртой линии по вертикали.
- Ну а остальные расположились по дефолту
Выглядит так:
Используя grid-gap, можно регулировать интервалы между элементами в контейнере. Делается это с помощью двух параметров:
- column-gap — расстояние между колонками;
- row-gap — расстояние между строками.
Вот как это выглядит в коде:
.container { column-gap: 1%; row-gap: 1%; }
Как и у grid-template, у gap есть сокращённая запись, где параметры column-gap и row-gap можно записать через пробел:
gap: 1% 1%;
Со свойствами элементов разобрались, теперь поговорим о том, как их выровнять в рамках контейнера или области.
Что делает: выравнивает элементы в пределах области по горизонтали.
Растягивает элементы на всю ширину грид-ячейки
Располагает элементы в левой части грид-ячейки или области
Располагает элементы в центре грид-ячейки или области
Располагает элементы в правой части грид-ячейки или области
Что делает: выравнивает элементы в пределах области по вертикали.
Растягивает элементы на всю длину грид-ячейки
Располагает элементы в верхней части грид-ячейки
Располагает элементы в центре грид-ячейки
Располагает элементы в нижней части грид-ячейки
Что делает: выравнивает элементы в пределах всего контейнера по горизонтали.
Располагает элементы в левой части грид-контейнера
Располагает элементы по центру грид-контейнера
Располагает все элементы в правой части грид-контейнера
justify-content: space-between;
Распределяет элементы по левому и правому краю. Первый элемент располагается ближе к началу, а последний — ближе к концу
justify-content: space-around;
Распределение с равным пространством между элементами и половиной этого пространства от краёв
justify-content: space-evenly;
Распределение с равным пространством и между элементами, и от краёв
Что делает: выравнивает элементы в пределах всего контейнера по вертикали.
Для начала увеличим высоту контейнера с помощью параметра height:
.container { display: grid; /* code... */ height: 200px; }
Пока элементы просто растянулись по длине контейнера, а теперь попробуем применить к нему следующие свойства:
Все элементы расположились в верхней части контейнера
Все элементы расположились в середине грид-контейнера
align-content: space-between;
Элементы расположились по верхнему и нижнему краю. Первый элемент ближе к началу, последний — ближе к концу
align-content: space-around;
Распределение с равным пространством между элементами и половиной этого пространства от краёв
Следующие свойства работают с отдельными грид-элементами, поэтому параметры мы будем прописывать не всему контейнеру, а элементу — скажем, с буквой A.
Что делает: выравнивает грид-элементы по горизонтали.
Элемент A растянулся по всей длине грид-области
Элемент A расположился в центре грид-области
Элемент A расположился в начале грид-области
Элемент A расположился в конце грид-области
Что делает: выравнивает грид-элементы по вертикали.
Элемент A растянулся по всей ширине грид-области
Элемент A расположился в середине грид-области
Элемент A расположился в начале грид-области
Элемент A расположился в конце грид-области
В CSS грид бывает вложенным — это значит, что он содержит в себе другой грид-контейнер. Чтобы понять, как это работает, давайте немного пересоберём наш HTML-каркас, добавив в него ещё один подуровень элементов:
<head> <title>CSS Grid Layout</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <div class="A">A</div> <div class="B">B</div> <div class="С">C</div> <!-- Тут начинается подуровень, содержащий 3 элемента --> <div class="D"> <div class="E">E</div> <div class="F">F</div> <div class="G">G</div> </div> <div class="H">H</div> <div class="J">J</div> </div> </body>
Для основного контейнера в CSS-файле создадим сетку 3 на 3:
/* Объявляем грид 3 × 3 */ .container { display: grid; grid-template-columns: repeat(3, 3fr); grid-template-rows: repeat(3, 3fr); }
И вот какая матрёшка у нас получилась:
А теперь для элемента D определим display: grid — то есть объявим внутри него ещё одну сетку. Для свойств строк и столбцов напишем параметр subgrid, который заимствует параметры родительского грида:
.D { display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; }
Готово! Теперь можно мастерски жонглировать элементами E, F, G, задавая им разное расположение в пределах элемента D (который тоже стал сеткой). Например, сделаем так, чтобы E начинался от второй вертикальной линии грида до третьей:
.E { grid-column: 2 / 3; }
Внутренние элементы, в свою очередь, расположились уже во вложенном гриде:
Сегодня мы узнали, что такое грид в 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 (по вертикали).
Научитесь: Профессия Frontend-разработчик PRO
Узнать больше
CSS Grid Layout — самая мощная система компоновки из доступных на данный момент в CSS. Это двумерная система, которая может обрабатывать как колонки так и строки, в отличии от Flexbox, который в значительной степени является одномерной системой. При работе с CSS Grid, вы применяете CSS правила и родительским элементам (которые становятся Grid контейнерами) и к дочерним элементам (которые становятся Grid элементами).
Введение
CSS Grid Layout (aka «Grid») — это двумерная система компоновки основанная на сетке, цель которой заключается в том чтобы полностью изменить способ проектирования пользовательских интерфейсов основанных на сетке. CSS всегда использовался для разметки веб-страниц, но никогда не делал эту работу хорошо. Сначала мы использовали таблицы, потом обтекания (floats), позиционирование и инлайновые блоки (inline-block), но все эти методы по существу являются просто хаками и опускают много важных функциональных возможностей (например, вертикальное выравнивание). Flexbox помог, но он предназначен для более простых одномерных макетов, а не для сложных двумерных (на самом деле Flexbox и Grid очень хорошо работают вместе). CSS Grid’ы — это первый модуль созданный специально для решения проблем компоновки, которые до сих пор мы решали с помощью хаков при создании сайтов. Есть две основные вещи, которые вдохновили меня на создание этого руководства. Первое, это замечательная книга от Rachel Andrew’s Get Ready for CSS Grid Layout. Это подробное и понятное введение в CSS Grid’ы, которое является основой для всей этой статьи. Я настоятельно рекомендую купить и прочитать его. Вторая вещь, которая меня вдохновила — это A Complete Guide to Flexbox (Полное руководство по Flexbox) от Chris Coyier’s, которая стала моим основным ресурсом по Flexbox. Она помогла большому количеству людей, о этом свидетельствует тот факт, что это лучший результат в поисковой выдаче при запросе»Flexbox» в Google. Вы увидите много похожего между этой статьей и моей, потому что почему бы не украсть у лучших?
Моя цель в этом руководстве — это возможность представить вам концепции CSS Grid’ов так как они существуют в самой последней версии спецификации. Поэтому я не буду освещать устаревший синтаксис для IE и сделаю всё возможное, чтобы это руководство регулярно обновлялось, по мере изменения спецификации.
Основы и поддержка браузерами
Для того чтобы начать работу, нам нужно определить элемент-контейнер с помощью display: grid, настроить размеры колонок и строк с помощью grid-template-columns и grid-template-rows, а также разместить его дочерние элементы внутри сетки с помощью grid-column и grid-row. Так же как и во Flexbox, порядок элементов в источнике сетки, не имеет значения (прим. переводчика: в HTML разметке). Ваш CSS может размещать их в любом порядке, что собственно упрощает перегруппировку сетки с помощью медиа запросов. Представьте, что вы определяете разметку всей страницы, а затем полностью переставляете её, чтобы разместить элементы под другую ширину экрана всего лишь с помощью нескольких CSS строк кода. CSS Grid — это один из самых мощных CSS модулей, представленных когда-либо. По состоянию на март 2017 года, многие браузеры уже поддерживают CSS Grid, без префиксов: Chrome (включая Android), Firefox, Safari (включая iOS), и Opera. Internet Explorer 10 и 11 поддерживают его но с реализацией более старого синтаксиса. Была анонсирована поддержка в Edge, но её пока нет.
CSS Grid Layout (level 1)
Полная поддержка
Частичная поддержка
С префиксом
Не поддерживается
Помимо Microsoft, производители браузеров по всей видимости придерживают запуск CSS Grid’ов в свободное плавание, пока спецификация не будет полностью готова. И это хорошо, потому что нам не придется заботится об изучении нескольких синтаксисов.
Это всего лишь вопрос времени, когда вы сможете использовать Grid’ы в продакшене. Но самое время, чтобы узнать о нём побольше.
Важная терминология
Перед тем как мы погрузимся в концепцию Grid’ов, важно понимать её терминологию. Так как используемые здесь термины концептуально похожи, их довольно легко перепутать друг с другом, если с самого начала не запомнить их значения, определённые в спецификации. Не волнуйтесь их не так много.
Контейнер сетки
Элемент к которому применяется display: grid. Это прямой родитель для всех элементов сетки. В этом примере container
является контейнером.
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
Элемент сетки
Дочерние элементы (прямые потомки) контейнера. Здесь item
это элемент сетки, но не sub-item
.
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>
Линия сетки
Разделительные линии, составляющие структуру для сетки. Они могут быть вертикальными («линии колонок») или горизонтальными («линии строк») и располагаться по обе стороны от строки или столбца. На изображении жёлтая линия является примером вертикальной линии (линией колонки).
Трек сетки
Пространство между двумя соседними линиями. Вы можете думать об этом как о столбцах или строках сетки. Вот трек между второй и третьей линией строк.
Ячейка сетки
Пространство между линиями двух соседних строк и двух соседних столбцов. Это отдельная «единица измерения» сетки. Вот пример ячейки между линиями строк 1 и 2, линиями колонок 2 и 3.
Область сетки
Общее пространство окружённое четырьмя линиями. Область может состоять из любого количества ячеек. Вот пример области между строками 1 и 3, и колонками 1 и 3.
Содержание
Свойства для контейнера
- display
- grid-template-columns
- grid-template-rows
- grid-template-areas
- grid-template
- grid-column-gap
- grid-row-gap
- grid-gap
- justify-items
- align-items
- justify-content
- align-content
- grid-auto-columns
- grid-auto-rows
- grid-auto-flow
- grid
Свойства для родительского элемента
(Контейнера сетки)
display
Определяет элемент как контейнер и устанавливает новый контекст форматирования сетки для его содержимого.
Значения:
- grid — формирует сетку как блок;
- inline-grid — формирует сетку как инлайновый блок;
- subgrid — если ваш контейнер это ещё и элемент (вложенная сетка), то вы можете использовать это свойство для обозначения того, чтобы размеры строк/колонок были взяты из родительского элемента, а не определяли собственный;
.container {
display: grid | inline-grid | subgrid;
}
Обратите внимание на то, что column
, float
, clear
и vertical-align
не дадут никакого эффекта на контейнере.
grid-template-columns
grid-tempate-rows
Определяет колонки и строки сетки с помощью списка значений разделённого пробелами. Значения представляют из себя размер трека, а пробелы между ними представляют линии сетки.
Значения:
- <track-size> — может быть фиксированным размером, процентами или частью свободного пространства в сетке (определяется с помощью единицы
fr
(fraction)); - <line-name> — произвольное имя на ваш выбор;
.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
Примеры:
Когда вы оставляете пустое пространство между значениями треков, линиям сетки автоматически присваиваются числовые имена:
.container{
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}
Но вы можете называть линии явно. Обратите внимание на синтаксис для их названия:
.container {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}
Обратите внимание на то что у линии может быть несколько названий. Например, здесь у второй линии будет два названия: row1-end
и row2-start
:
.container{
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}
Если в вашем определении содержатся повторяющиеся части, то можно использовать нотацию repeat()
:
.container {
grid-template-columns: repeat(3, 20px [col-start]) 5%;
}
Тоже самое что и:
.container {
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}
Единица fr позволяет вам настраивать размер треков как часть свободного пространства в контейнере. Вот пример, который устанавливает каждому элементу одну третью ширины контейнера.
.container {
grid-template-columns: 1fr 1fr 1fr;
}
Свободное пространство высчитывается после вычисления всех фиксированных элементов. В этом примере, общее количество свободного пространства для единиц fr не будет включать в себя 50px.
grid-template-areas
Определяет шаблон сетки ссылаясь на имена областей, которые заданы с помощью свойства grid-area. Повторение названия области приводит к тому, что содержимое охватывает эти ячейки. Точка означает пустую ячейку. Сам синтаксис предоставляет визуализацию структуры сетки.
Значения:
- <grid-area-name> — имя области заданное с помощью grid-area;
- . — точка обозначающая пустую ячейку;
- none — области не определены;
.container {
grid-template-areas:
"<grid-area-name> | . | none | ..."
"...";
}
Пример:
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}
.container {
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}
Пример выше создаст сетку из 4 колонок и 3 строк. Вся верхняя строка будет состоять из области header. Строка по середине будет состоять из области main, занимающей две колонки, пустой ячейки и области sidebar, которая занимает одну колонку. Последняя строка будет состоять только из области footer.
У каждой строки должно быть одинаковое количество ячеек. Вы можете использовать любое количество примыкающих точек для объявления пустых ячеек. Пока между точками нет пробелов, они представляют одну ячейку.
Обратите внимание на то, что вы никак не называете линии, только области. Когда вы используете такой синтаксис, линии на обоих концах областей будут именоваться автоматически. Если ваша область называется foo, то название первых линий для строк и столбцов будет foo-start, а название для последних линий строк и столбцов будет foo-end. Это означает, что у некоторых линий может быть несколько имён, как нашем случае, у самой левой линии будет три названия: header-start, main-start, и footer-start.
grid-template
Сокращение для grid-template-rows, grid-template-columns, и grid-template-areas.
Значения:
- none — устанавливает все три свойства в их начальное значение;
- subgrid — устанавливает grid-template-rows и grid-template-columns в
subgrid
, и grid-template-areas в его начальное значение; - <grid-template-rows> / <grid-template-columns> — устанавливает grid-template-columns и grid-template-rows в определённое значение, соответственно, и устанавливает grid-template-areas в
none
;
.container {
grid-template: none | subgrid | <grid-template-rows> / <grid-template-columns>;
}
Он также принимает более сложный, но довольно удобный синтаксис, для указания всех трёх свойств. Вот пример:
.container {
grid-template:
[row1-start] 25px "header header header" [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
Что эквивалентно следующему:
.container {
grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
grid-template-areas:
"header header header"
"footer footer footer";
}
Так как grid-template
не сбрасывает неявные свойства (grid-auto-columns, grid-auto-rows, и grid-auto-flow), а в большинстве случаев, вероятно, вы бы захотели это сделать, рекомендуется использовать свойство grid, вместо grid-template
.
# grid-column-gap
grid-row-gap
Определяет размер ширины линий. Вы можете думать об этом, как о настройке ширины отступов между столбцами и строками.
Значения:
- <line-size> — значение размера;
.container {
grid-column-gap: <line-size>;
grid-row-gap: <line-size>;
}
Пример:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-column-gap: 10px;
grid-row-gap: 15px;
}
Отступы создаются только между колонками и строками, но не для внешних краев сетки.
grid-gap
Сокращение для grid-row-gap и grid-column-gap.
Значение:
- <grid-row-gap> <grid-column-gap> — значения размеров;
.container {
grid-gap: <grid-row-gap> <grid-column-gap>;
}
Пример:
.container{
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-gap: 10px 15px;
}
Если значение для grid-row-gap не задано, ему присваивается такое же значение как и у grid-column-gap.
justify-items
Выравнивает содержимое вдоль оси строки (в отличии от align-items который выравнивает элементы вдоль оси столбца). Это значение применяется ко всем элементам сетки внутри контейнера.
Значения:
- start — выравнивает содержимое по левой стороне области;
- end — выравнивает содержимое по правой стороне области;
- center — выравнивает содержимое по центру области;
- stretch — заполняет всю ширину области (по умолчанию);
.container {
justify-items: start | end | center | stretch;
}
Примеры:
.container {
justify-items: start;
}
.container{
justify-items: end;
}
.container{
justify-items: center;
}
.container{
justify-items: stretch;
}
align-items
Выравнивает содержимое вдоль оси столбца (в отличии от justify-items который выравнивает элементы вдоль оси строки). Это значение применяется ко всем элементам сетки внутри контейнера.
Значения:
- start — выравнивание элементов по верхней части области;
- end — выравнивание элементов по нижней части области;
- center — выравнивание элементов по центру области;
- stretch — заполняет всю высоту области (по умолчанию);
.container {
align-items: start | end | center | stretch;
}
Примеры:
.container {
align-items: start;
}
.container {
align-items: end;
}
.container {
align-items: center;
}
.container {
align-items: stretch;
}
justify-content
Иногда общий размер сетки может быть меньше размера контейнера. Такое может случится если у всех элементов сетки заданы фиксированные единицы измерения, например px
. В таком случае можно установить выравнивание сетки внутри контейнера. Это свойство выравнивает сетку вдоль оси строки (в отличии от свойства align-content, которое выравнивает сетку вдоль оси столбца).
Значения:
- start — выравнивает сетку по левой стороне контейнера;
- end — выравнивает сетку по правой стороне контейнера;
- center — выравнивает сетку по центру контейнера;
- stretch — масштабирует элементы чтобы сетка могла заполнить всю ширину контейнера;
- space-around — одинаковое пространство между элементами, и полуразмерные отступы по краям;
- space-between — одинаковое пространство между элементами, без отступов по краям;
- space-evenly — одинаковое пространство между элементами, и полноразмерные отступы по краям;
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
Примеры:
.container {
justify-content: start;
}
.container {
justify-content: end;
}
.container {
justify-content: center;
}
.container {
justify-content: stretch;
}
.container {
justify-content: space-around;
}
.container {
justify-content: space-between;
}
.container {
justify-content: space-evenly;
}
align-content
Иногда общий размер сетки может быть меньше размера контейнера. Такое может случится если у всех элементов сетки зада фиксированные единицы измерения, например px
. В таком случае можно установить выравнивание сетки внутри контейнера. Это свойство выравнивает сетку вдоль оси колонки (в отличии от свойства justify-content, которое выравнивает сетку вдоль оси строки).
Значения:
- start — выравнивает сетку по верхней части контейнера;
- end — выравнивает сетку по нижней части контейнера;
- center — выравнивает сетку по центру контейнера;
- stretch — масштабирует элементы чтобы сетка могла заполнить всю высоту контейнера;
- space-around — одинаковое пространство между элементами, и полуразмерные отступы по краям;
- space-between — одинаковое пространство между элементами, без отступов по краям;
- space-evenly — одинаковое пространство между элементами, и полноразмерные отступы по краям;
.container {
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
Примеры:
.container {
align-content: start;
}
.container {
align-content: end;
}
.container {
align-content: center;
}
.container {
align-content: stretch;
}
.container {
align-content: space-around;
}
.container {
align-content: space-between;
}
.container {
align-content: space-evenly;
}
grid-auto-columns
grid-auto-rows
Определяет размер любых автоматически созданных треков (иначе говоря, неявных треков). Неявные треки создаются при явном позиционировании столбцов и строк (через grid-template-rows/grid-template-columns), которые находятся за пределами заданной сетки.
Значения:
- <track-size> — может быть фиксированным размером, процентами, или частью свободного пространства в сетке (с использованием единицы
fr
);
.container {
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;
}
Чтобы проиллюстрировать то как создаются неявные треки, посмотрите на это:
Пример выше создаст сетку 2 x 2.
А теперь представьте, что вы позиционируете элементы сетки с помощью grid-column и grid-row следующим образом:
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
Мы сказали чтобы элемент .item-b начинался с 5 линии и заканчивался на 6 линии, по оси столбцов, но мы не определяли линии 5 и 6. Так как мы ссылаемся на не существующие линии, неявные треки с шириной 0 были созданы чтобы заполнить пробелы. Мы можем использовать grid-auto-columns и grid-auto-rows чтобы указать ширину этим неявным трекам:
.container {
grid-auto-columns: 60px;
}
grid-auto-flow
Если у вас есть элементы, которые вы явно не позиционируете в сетке, запускается алгоритм авто-размещения, чтобы их автоматически разместить. Это свойство контролирует то как алгоритм авто-размещения работает.
Значения:
- row — говорит алгоритму авто-размещения заполнять каждую строку поочерёдно, добавляя новые строки при необходимости;
- column — говорит алгоритму авто-размещения заполнять каждую колонку поочерёдно, добавляя новые колонки при необходимости;
- dense — говорит алгоритму авто-размещения попытаться заполнить дыры в сетке, если более мелкие элементы появляются позже;
.container {
grid-auto-flow: row | column | row dense | column dense
}
Обратите внимание на то что dense может привести к тому, что ваши элементы будут отображаться не по порядку.
Примеры:
Рассмотрим следующий HTML:
<section class="container">
<div class="item-a">item-a</div>
<div class="item-b">item-b</div>
<div class="item-c">item-c</div>
<div class="item-d">item-d</div>
<div class="item-e">item-e</div>
</section>
Вы определили сетку с пятью колонками и двумя рядами, а свойство grid-auto-flow
установили в row
(оно же значение по умолчанию).
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}
При размещении элементов в сетке, вы указываете позиции только для двух из них:
.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}
Так как мы установили grid-auto-flow
в row
, наша сетка будет выглядеть как на изображении ниже. Обратите внимание на то, как три элемента которые мы не расположили (item-b, item-c и item-d) перетекают через пустые строки:
Если вместо этого мы установим свойство grid-auto-flow
в column
, элементы item-b, item-c and item-d будут перетекать сквозь колонки:
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: column;
}
grid
Сокращение для настройки всех следующих свойств: grid-template-rows, grid-template-columns, grid-template-areas, grid-auto-rows, grid-auto-columns, и grid-auto-flow. Он также настраивает grid-column-gap и grid-row-gap на их начальные значения, даже если они не могут быть явно заданы этим свойством.
Значения:
- none — настраивает все свойства на их начальные значения;
- <grid-template-rows> / <grid-template-columns> — настраивает grid-template-rows и grid-template-columns на соответствующие указанные значения, а все остальные свойства сбрасывает к их начальным значениям;
- <grid-auto-flow> [<grid-auto-rows> [ / <grid-auto-columns>] ] — принимает те же самые значения что и grid-auto-flow, grid-auto-rows и grid-auto-columns, соответственно. Если grid-auto-columns опущено, устанавливается значение соответствующие для grid-auto-rows. Если опущены оба, то они устанавливаются в начальные значения;
.container {
grid: none | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [/ <grid-auto-columns>]];
}
Примеры:
Следующие два блока кода эквивалентны:
.container {
grid: 200px auto / 1fr auto 1fr;
}
.container {
grid-template-rows: 200px auto;
grid-template-columns: 1fr auto 1fr;
grid-template-areas: none;
}
И следующие два блока также эквивалентны:
.container {
grid: column 1fr / auto;
}
.container {
grid-auto-flow: column;
grid-auto-rows: 1fr;
grid-auto-columns: auto;
}
Он также принимает более сложный, но довольно удобный синтаксис для настройки всего и сразу. Вы указываете grid-template-areas, grid-template-rows и grid-template-columns, а все остальные свойства устанавливаются в начальные значения. Всё что вы делаете, это указываете имена строк и размеры треков в строке соответствующим областям сетки. Это проще всего описать на примере:
.container {
grid: [row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
Это эквивалентно следующему:
.container {
grid-template-areas:
"header header header"
"footer footer footer";
grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
}
Свойства для дочерних элементов
(Grid элементы)
grid-column-start
grid-column-end
grid-row-start
grid-row-end
Определяют местоположение в сетке ссылаясь на конкретные линии. grid-column-start
/grid-row-start
— это линия с которой начинается элемент, а grid-column-end
/grid-row-end
— это линия на которой элемент заканчивается.
Значения:
- <line> — может быть числом ссылающимся на пронумерованную линию, или названием ссылающимся на именованую линию;
- span <number> — элемент, который будет охватывать предоставленное количество треков;
- span <name> — элемент будет будет охватывать пока не достигнет линии с указанным названием;
- auto — указывает автоматическое размещения, автоматическое охват, или охват по умолчанию;
.item {
grid-column-start: <number> | <name> | span <number> | span <name> | auto
grid-column-end: <number> | <name> | span <number> | span <name> | auto
grid-row-start: <number> | <name> | span <number> | span <name> | auto
grid-row-end: <number> | <name> | span <number> | span <name> | auto
}
Примеры:
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start
grid-row-end: 3
}
.item-b {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2
grid-row-end: span 2
}
Если grid-column-end
/grid-row-end
не объявлены, элемент будет охватывать 1 трек по умолчанию.
grid-column
grid-row
Сокращение для grid-column-start + grid-column-end, и grid-row-start + grid-row-end, соответственно.
Значения:
- <start-line> / <end-line> — каждый из них принимает тоже самое, что и в длинной версии, включая охват;
.item {
grid-column: <start-line> / <end-line> | <start-line> / span <value>;
grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}
Пример:
.item-c {
grid-column: 3 / span 2;
grid-row: third-line / 4;
}
Если значение конечной линии не указано, то элемент будет охватывать только 1 трек, по умолчанию.
grid-area
Даёт название элементу чтобы можно было ссылаться на него с помощью шаблона созданного через grid-template-areas свойство. В качестве альтернативы, это свойство может быть использовано в качестве сокращения для grid-row-start + grid-column-start + grid-row-end + grid-column-end.
Значения:
- <name> — название, которое вы выберите;
- <row-start> / <column-start> / <row-end> / <column-end> — может быть нумерацией или названиями линий;
.item {
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}
Примеры:
Как способ назначить название элементу:
.item-d {
grid-area: header
}
Как сокращение для grid-row-start
+ grid-column-start
+ grid-row-end
+ grid-column-end
:
.item-d {
grid-area: 1 / col4-start / last-line / 6
}
justify-self
Выравнивает содержимое элемента вдоль оси строки (в отличии от align-self, который выравнивает вдоль оси столбца). Это значение применяется к содержимому внутри отдельного элемента.
Значения:
- start — выравнивает содержимое по левой части области;
- end — выравнивает содержимое по правой части области;
- center -выравнивает содержимое по центру области;
- stretch — заполняет всю ширину области (по умолчанию);
.item {
justify-self: start | end | center | stretch;
}
Примеры:
.item-a {
justify-self: start;
}
.item-a {
justify-self: end;
}
.item-a {
justify-self: center;
}
.item-a {
justify-self: stretch;
}
align-self
Выравнивает содержимое элемента вдоль оси столбца (в отличии от justify-self, который выравнивает вдоль оси строки). Это значение применяется к содержимому внутри отдельного элемента.
Значения:
- start — выравнивает содержимое по верхней части области;
- end — выравнивает содержимое по нижней части области;
- center -выравнивает содержимое по центру области;
- stretch — заполняет всю высоту области (по умолчанию);
.item {
align-self: start | end | center | stretch;
}
Примеры:
.item-a {
align-self: start;
}
.item-a {
align-self: end;
}
.item-a {
align-self: center;
}
.item-a {
align-self: stretch;
}
На чтение 13 мин Просмотров 36.4к. Опубликовано 23.06.2021
CSS Grid Layout — это двумерная сетка для для размещения элементов страницы. Верстая с данной технологией, надо думать столбцами и рядами, как в таблице. По сути, Grid CSS — это набор свойств, при помощи которых можно расположить элементы в нужном порядке, в нужном размере ячейках и задать расстояния между ними.
Содержание
- Видео урок по CSS Grid
- Основы Grid CSS: колонки, ряды, отступы
- Фракции
- Функция repeat() для повторяющихся колонок и рядов
- Функция minmax() для отзывчивых колонок
- Функция minmax() для отзывчивых рядов
- Направление контента в сетке
- Неявная сетка
- Автоперенос контента: свойства auto-fill и auto-fit
- Перемещение ячеек, линии сетки
- Выравнивание ячеек внутри колонок и рядов
- Сокращенное определение колонок и рядов с grid-template
- Области сетки Grid Areas
- Вложенные сетки
- Заключение
Видео урок по CSS Grid
Основы Grid CSS: колонки, ряды, отступы
Контейнер. Во-первых, нужно создать контейнер, у нас с классом .grid
, внутри которого будут находится элементы сетки, в нашем случае 9 элементов <div>
. Сетка создается на контейнере и все элементы внутри него выстраиваются по заданной сетке. Просто добавляем к CSS контейнера свойство display: grid;
После этого можно указывать прочие свойства Grid. Но пока не заданы другие свойства сетки, элементы выстроены вертикально друг за другом так, как они идут в html разметке.
Колонки. За колонки отвечает свойство grid-template-columns
. В значении свойства указывается размер каждой колонки через пробел. Например, три колонки по 100 px каждая: grid-template-columns: 100px 100px 100px;
Элементы распределятся в три колонки.
Ряды. За ряды отвечает свойство grid-template-rows
. Задать высоту рядам по 100px: grid-template-rows: 100px 100px 100px;
Отступы. Добавим пространство между колонками при помощи grid-column-gap
и пространство между рядами при помощи grid-row-gap
. Эти свойства можно объединить в grid-gap: 20px 30px;
, где первое значение — отступ между рядами, а второе — между колонками. Если нужен одинаковый отступ между колонками и рядами, задаем его одним значением grid-gap: 20px;
Чтобы понять основы Grid CSS, увидеть код и результат, потренироваться, задавая разные значения свойств вручную, переходи на этот учебный пример Codepen Webcademy.
See the Pen CSS Grid — №1 Основы by Webcademy.ru online school (@webcademy) on CodePen.dark
Фракции
Фракция — специальная единица измерения CSS Grid для создания адаптивного макета. Фракция — это часть целого.
Если определить три колонки, шириной 1 фракция каждая (1fr
), колонки будут равномерно делить ширину экрана или свободного для них пространства и занимать по 1 части каждая.
grid-template-columns: 1fr 1fr 1fr;
вся доступная ширина разделилится на 3 части и каждая колонка займет одну из этих частей.
grid-template-columns: 2fr 1fr 1fr;
доступная ширина поделится на 4 части, первая колонка займет две части, а остальные колонки — по одной части.
Фракции можно комбинировать с точными единицами измерения.
grid-template-columns: 200px 1fr 1fr;
первая колонка займет фиксированную ширину в 200px, а две другие будут делить оставшееся пространство между собой поровну. При изменении ширины экрана, первая колонка будет также занимать 200px, а ширина колонок, заданная во фракциях, будет пересчитываться.
Проверить и потренироваться можно тут.
See the Pen CSS Grid — №2 Фракции by Webcademy.ru online school (@webcademy) on CodePen.dark
Функция repeat()
для повторяющихся колонок и рядов
repeat()
позволяет задавать количество и размер колонок без повторений в коде.
Запись grid-template-columns: 1fr 1fr 1fr 1fr;
равнозначна grid-template-columns: repeat(4, 1fr);
, где первое значение — число колонок, второе — ширина каждой колонки.
Запись grid-template-columns: 50px 200px 50px 200px;
равнозначна grid-template-columns: repeat(2, 50px 200px);
, размеры указаны через пробел без запятой. Означает: повторить 2 раза комбинацию колонок шириной 50 и 200px. Посмотрим на результат:
See the Pen CSS Grid — №3 repeat by Webcademy.ru online school (@webcademy) on CodePen.dark
Функция minmax()
для отзывчивых колонок
minmax()
позволяет задать размер, в зависимости от ширины окна. Первый аргумент — минимальный размер, второй — максимальный. При изменении размера окна, ширина колонки будет меняться в заданном диапазоне.
grid-template-columns: minmax(100px, 500px) 100px 100px 100px;
здесь первая колонка резиновая, а остальные с фиксированным размером. При достижении минимального размера, колонка перестает уменьшаться. Если продолжать уменьшать окно, то появляется горизонтальная полоса прокрутки.
Чтобы лично проверить и убедиться в резиновости первой колонки, жми сюда.
See the Pen CSS Grid — №4 minmax by Webcademy.ru online school (@webcademy) on CodePen.dark
Функция minmax()
для отзывчивых рядов
К рядам minmax()
тоже применим.
grid-template-rows: 50px minmax(50px, auto) 50px;
значение auto
указывает на то, что ряд будет расширяться настолько, насколько этого потребует контент.
Направление контента в сетке
По умолчанию контент в сетке располагается в направлении ряда слева направо.
За направление контента отвечает свойство grid-auto-flow
.
По умолчанию со значением row
: размещать элементы, заполняя поочерёдно каждую строку и добавляя новые строки по мере необходимости.
Значение column
: контент выстроится в направлении колонок сверху вниз. Элементы теперь будут размещаться, заполняя поочерёдно каждый столбец и добавляя новые столбцы по мере необходимости.
Обратите внимательно на расположение ячеек в сетке при grid-auto-flow: row;
и grid-auto-flow: column;
.
Протестировать свойство можно тут.
See the Pen CSS Grid — №5 направление контента by Webcademy.ru online school (@webcademy) on CodePen.dark
Неявная сетка
Разберем примеры явной и неявной сеток.
.grid { display: grid; grid-template-columns: 200px 200px 200px; grid-template-rows: 100px 100px; grid-gap: 20px; }
Получаем 2 ряда по 100px, как было указано, и ещё один ряд контента, который не поместился и был автоматически перенесен в третий ряд без фиксированной высоты.
Явная сетка в данном случае будет та, которую мы обозначили свойствами grid-template-columns: 200px 200px 200px;
и grid-template-rows: 100px 100px;
Неявная сетка — прочие ряды и колонки, которые созданы автоматически, поскольку контент не поместился в явную сетку. Неявной сеткой можно управлять при помощи свойств grid-auto-rows
и grid-auto-columns
.
See the Pen CSS Grid — №6 Неявная сетка by Webcademy.ru online school (@webcademy) on CodePen.dark
Потренируйтесь работать со свойствами тут. Попробуйте сами убрать свойство автозаполнения и для колонок: grid-auto-columns
и обратите внимание, как ведут себя ячейки при наличии grid-auto-flow: column;
Автоперенос контента: свойства auto-fill и auto-fit
Избежать горизонтальный скролл и сделать, чтобы элементы переносились на новую строку с нужной шириной колонок помогут функции minmax()
и repeat()
и свойства auto-fill
и auto-fit
.
Например, сетка на 6 колонок по 200px и они не помещаются в ширину окна, возникает горизонтальная прокрутка. Задаем функцию repeat()
, где повторение колонок будет автоматическим по свойству auto-fit
(либо auto-fill
), а размер колонок будет регулировать функция minmax()
от минимального 50px до 1fr (делить все доступное пространство на количество колонок).
.auto-fit { grid-template-columns: repeat(auto-fit, minmax(50px, 1fr)); }
auto-fill
стремится поместить в строку как можно больше ячеек. Это свойство предпочитает использовать минимальную ширину для ячейки, даже если есть свободное место.
auto-fit
стремится занять всё доступное пространство в строке и подстраивает ширину ячеек под это пространство.
В обоих случаях происходит перенос ячеек на новую строчку, количество колонок подстраивается под размер сетки. Но при наличии свободного пространства auto-fill
использует минимальную ширину колонки, а auto-fit
подстраивает ширину под свободное место. Такое поведение мы наблюдаем, когда свободного пространства много и очевидна разница в работе этих свойств. В том случае, если пространства недостаточно и происходит перенос на новую строку, разница в работе свойств становится незаметной.
Самостоятельно проверять тут.
See the Pen CSS Grid — №7 Свойства auto-fill и auto-fit by Webcademy.ru online school (@webcademy) on CodePen.dark
Перемещение ячеек, линии сетки
Линии сетки — это условные линии по горизонтали и вертикали, между которыми располагаются ячейки.
Синим обозначены горизонтальные линии сетки и красным — вертикальные. Нумерация линий сетки слева направо и сверху вниз, либо в обратном направлении со знаком минус:
Можно перемещать ячейки по линиям и давать им команду занять место, растянуться, между определенными линиями.
Передвижение между вертикальными линиями (по колонкам)
grid-column-start
свойство указывает то, с какой вертикальной линии начнется ячейка
grid-column-end
свойство указывает на то, на какой вертикальной линии ячейка закончится
grid-column: 2 / 4;
используется вместо предыдущих свойств. Здесь первое значение — линия старта, второе через косую черту — линия окончания ячейки.
Например, обратимся к 1 ячейке. Сейчас она располагается между вертикальными линиями 1 и 2 (или -5 и -4). Будем стилизовать ее по селектору потомства :nth-child(1)
.
.grid > div:nth-child(1)
обращаемся к контейнеру .grid
и далее к первому входящему в него диву > div:nth-child(1)
При помощи свойств grid-column-start: 2;
и grid-column-end: 4;
расположим ее между 2 и 4 линиями. Ячейка при этом займет 2 колонки.
Можно растянуть ячейку на весь первый ряд.
Для этого будем использовать обратную нумерацию для окончания: grid-column: 1 / -1;
Передвижение между горизонтальными линиями (по рядам)
Переместим ячейку 2 из предыдущего примера на первый ряд.
Стилизуем по селектору .grid > div:nth-child(2)
.
У рядов, как и у колонок есть отдельные свойства для обозначения старта и финиша ячейки: grid-row-start
и grid-row-end
. Но можно использовать одно свойства для двух значений, указанных через косую черту grid-row
. Второе значение можно не указывать, если хотим, чтобы ячейка занимала только один ряд.
.grid > div:nth-child(1) { /* grid-column-start: 1; */ /* grid-column-end: -1; */ grid-column: 1 / -1; } .grid > div:nth-child(2) { grid-column: 2 / 4; /* grid-row-start: 1; */ grid-row: 1; }
Плавающие ячейки
Интересная особенность сетки заключается в том, что если у ячейки не определен ряд, то она является плавающей и свободное место рядом с ней ничто не может заполнить. Как только мы определим ряд свойством grid-row
, это будет знаком для других ячеек, что есть свободное место и можно его занять.
В примере выше определен ряд для ячейки 2. Но место вокруг нее пустует. Это потому, что ячейка 1 по прежнему остается плавающей. Определим ряд для ячейки 1 и свободное место займут ячейки 3 и 4.
.grid > div:nth-child(1) { /* grid-column-start: 2; */ /* grid-column-end: 4; */ grid-column: 1 / -1; grid-row: 2; } .grid > div:nth-child(2) { grid-column: 2 / 4; /* grid-row-start: 1; */ grid-row: 1; }
А тут можно вручную подвигать ячейки туда-сюда для закрепления свойств.
See the Pen CSS Grid — №8 Перемещение ячеек внутри сетки by Webcademy.ru online school (@webcademy) on CodePen.dark
Выравнивание ячеек внутри колонок и рядов
По умолчанию ячейки тянутся на всю ширину колонки и ряда. За это отвечают свойства justify-items
для колонок и align-items
для рядов. Итак, по умолчанию их значение stretch
— то есть растягиваться на всю ширину.
Другие значения свойства:
start
— ячейка прилипает к началу колонки или ряда
end
— ячейка прилипает к концу колонки или ряда
center
— ячейка располагается по центру
Сравним поведение ячеек при использовании различных комбинаций этих свойств и значений. Для этого следует задать сначала задать фиксированные ширины для колонок и grid-auto-rows: minmax(100px, auto);
для рядов — что бы видеть поведение ячеек при дальнейших манипуляциях.
See the Pen CSS Grid — №9 Выравнивание ячеек by Webcademy.ru online school (@webcademy) on CodePen.dark
Тренируйтесь тут. Попробуйте добавлять больше контента в некоторые ячейки. И не забывайте заглядывать в инспектор (нажатием F12), увидите, что размеры колонок остаются неизменными.
Сокращенное определение колонок и рядов с grid-template
Это свойство позволяет сокращенно описать колонки и ряды.
Синтаксис такой: описание рядов / описание колонок.
grid-template: rows / columns;
То есть, вместо двух строчек кода:
grid-template-columns: 150px 150px 150px 150px;
grid-template-rows: 100px 100px 100px;
Можно использовать одну:
grid-template: 100px 100px 100px / 150px 150px 150px 150px;
А ещё лучше не забывать про функцию repeat()
grid-template: repeat(3, 100px) / repeat(4, 150px);
Поработать со свойством сюда.
See the Pen CSS Grid — №10 Свойство grid template by Webcademy.ru online school (@webcademy) on CodePen.dark
Области сетки Grid Areas
CSS Grid Area — области сетки. Например, то, что бывает в обычном макете страницы: хедер, футер, главная часть и сайдбар. При помощи данного инструмента верстают различные раскладки. Мы попробуем на примере такой:
Обратите внимание: здесь сайдбар находится наравне с футером по нижней границе.
По сути, мы видим две колонки и три ряда. Ячейка Header заняла весь первый ряд. Ячейка Sidebar растянулась на 3 и 4 ряд в первой колонке. И это поведение можно описать при помощи уже известных нам свойств grid-column
и grid-row
, но это плохо воспринимается визуально и вы не сразу поймете с какой раскладкой имеете дело, глядя только в код.
А можно воспользоваться инструментом Grid Area:
1). Описываем привычным способом колонки и ряды.grid-template-columns: 200px 1fr;
grid-template-rows: 100px 1fr 100px;
2). Описываем раскладку в свойстве grid-template-areas
.
Просто называем сущности так как нам удобно. В данном случае по содержимому. И поехали. Первый ряд описываем в двойных кавычках через пробел: первую и вторую ячейку первого ряда занимает header Пробел и описываем второй ряд: первая ячейка — aside, вторая — main. Таким же образом описываем третий ряд. получается весьма наглядно:grid-template-areas:
"header header"
"aside main"
"aside footer";
3). Каждому тегу присваиваем имя области через grid-area
header { grid-area: header;}
4). Для того, чтобы Footer оказался внизу, а Main занял все свободное место, следует добавить html, body { margin:0; height: 100%; }
Поработать с областями сетки сюда.
See the Pen CSS Grid — №11 Области сетки Grid Areas by Webcademy.ru online school (@webcademy) on CodePen.dark
Вложенные сетки
Внутри элементов сетки можно создавать вложенные сетки. То есть каждый элемент сетки может стать grid-контейнером со свойством display: grid;
Пример тут.
See the Pen CSS Grid — №12 Вложенные сетки by Webcademy.ru online school (@webcademy) on CodePen.dark
Заключение
Технология Grid CSS позволяет верстать любые раскладки, включая вложенность более мелких сеток в крупные.
Свойства Grid определяют размер и расположение элементов-ячеек в общей сетки, отступы между ними и выравнивание контента по горизонтали и вертикали.
При помощи технологии grid-areas, можно сделать так, что не смотря в окно браузера, а только в редактор кода, вы поймете, какой макет сверстан.
Сегодня мы изучим свойства CSS Grid, чтобы вы могли создавать адаптивные сайты. Мы объясним, как работает каждое из свойств Grid и дадим шпаргалку, которая охватывает все, что можно сделать с помощью Grid.
Это — перевод оригинальной статьи на freeCodeCamp от автора Joy Shaheb.
Ещё у нас есть видеоверсия урока от автора (осторожно, английский язык):
Grid — это схема или сетка для создания веб-сайтов.
Модель Grid позволяет компоновать содержимое вашего сайта. Кроме того, она помогает создавать структуры для адаптивных веб-сайтов. Ваш сайт будет хорошо выглядеть на ПК, на смартфоне и планшете.
Вот демо, сделанное на Grid в качестве основного чертежа.
Вид на ПК:
Мобильный вид:
Архитектура CSS Grid
Как работает архитектура Grid? Элементы Grid распределяются вдоль осей X и Y. Используя свойства Grid, вы можете создать макет сайта и управлять контентом на странице.
При этом в Grid вы можете объединять несколько строк и столбцов, как в программе Excel, что дает вам больше гибкости и возможностей, чем Flexbox.
Кстати, вот шпаргалка, которую я сделал для Flexbox, если вы хотите узнать об этом больше.
Вот шпаргалка, которая содержит все свойства Grid. Свойства сетки делятся на:
- Родительские свойства.
- Дочерние свойства.
Примечание: Красным цветом выделены сокращенные свойства.
К концу этого урока у вас будет четкое понимание того, как всё это использовать.
Как настроить проект
Для этого проекта вам нужно знать немного HTML и CSS и как работать с VS-кодом. Сделайте следующее:
- Создайте папку с именем «Project-1» и откройте VS Code.
- Создайте файлы index.html и style.css.
- Установите Live Server и запустите его.
Или вы можете просто открыть Codepen и начать кодить.
HTML
Создайте три блока внутри тега body.
<div class="container">
<div class="box-1"> A </div>
<div class="box-2"> B </div>
<div class="box-3"> C </div>
</div>
CSS
Очистите стили браузера по умолчанию.
*{
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
Внутри селектора body выполните следующее:
body {
font-family: sans-serif;
font-size: 40px;
width: 100%;
min-height: 100vh;
}
Теперь давайте зададим стили всем нашим блокам:
[class^="box-"] {
background-color: skyblue;
/* To place the letter at the center */
display: grid;
place-items: center;
}
Примечание: мы подробно обсудим эти свойства сетки позже.
Теперь добавьте промежутки между блоками.
.container {
display: grid;
gap: 20px;
}
Прежде чем начать, необходимо понять взаимоотношения между родительскими и дочерними классами.
Для родительского свойства Grid мы будем кодить внутри класса .container
.
Для дочернего свойства Grid мы будем кодить в классах .box-*
.
Родительские свойства CSS Grid
Изучим родительские свойства CSS Grid.
Свойство grid-template-columns
Это свойство используется для определения количества и ширины колонок сетки.
Вы можете задать ширину каждой колонки по отдельности или установить единую ширину для всех колонок с помощью функции repeat()
.
Напишите это в CSS:
.container {
display: grid;
gap: 20px;
/* Change the values ???? to experiment */
grid-template-columns: 200px auto 100px;
}
Значения пикселей будут точным измерением. Ключевое слово "auto"
будет охватывать все доступное пространство.
Если в качестве единицы измерения использовать fr
(это — дробная единица), все поля будут одинакового размера.
Свойство grid-template-rows
Это свойство используется для определения количества и высоты рядов.
Вы можете задать высоту каждой строки или установить единую высоту для всех строк с помощью функции repeat()
.
Напишите следующий код CSS:
.container {
display: grid;
gap: 20px;
height: 100vh;
/* Change the values ???? to experiment */
grid-template-rows: 200px auto 100px;
}
Свойство grid-template-areas
Это свойство указывает количество мест, которые ячейка сетки должна занимать в столбцах и строках родительского контейнера.
С этим свойством жизнь становится намного проще, так как оно позволяет нам видеть, что мы делаем.
Назовем это чертежом нашего макета.
Чтобы экспериментировать с ним, нужно понять свойства родительского и дочернего шаблонов:
- grid-template-areas: родительское свойство, которое будет создавать чертеж;
- grid-area: дочернее свойство, которое будет следовать за чертежом.
Сначала создайте чертеж внутри родительского класса .container
:
.container {
display: grid;
gap: 20px;
height: 100vh;
grid-template-areas:
"A A A A A A A A A A A A"
"B B B B B B B B B B C C"
"B B B B B B B B B B C C";
}
Выберите все дочерние классы .box-*
и установите такие значения:
.box-1{
grid-area: A;
}
.box-2{
grid-area: B;
}
.box-3{
grid-area: C;
}
Примечание: Мы ещё обсудим свойство grid-area
в разделе о дочерних свойствах сетки.
Свойство column-gap
Это свойство используется для размещения промежутков между столбцами внутри сетки.
Напишите в CSS следующее:
.container {
display: grid;
height: 100vh;
grid-template-columns: 100px 100px 100px;
//Change values???? to experiment
column-gap: 50px;
}
Примечание: column-gap
работает с grid-template-columns
.
Свойство row-gap
Это свойство размещает промежутки между строками.
Проверяем:
.container {
display: grid;
height: 100vh;
grid-template-rows: 100px 100px 100px;
// Change ???? values to experiment
row-gap: 50px;
}
Примечание: row-gap
работает с grid-template-rows
.
Свойство justify-items
Это свойство позиционирует дочерние элементы сетки внутри контейнеров вдоль оси X. Имеется 4 значения:
Если вы хотите проверить его, добавьте новое поле внутри HTML:
<div class="container">
<!--Other boxes - A, B, C are here-->
<div class="box-4"> D </div>
</div>
Настройте CSS:
.container {
display: grid;
gap: 50px;
height: 100vh;
// each box is 200px by 200px
grid-template-rows: 200px 200px;
grid-template-columns: 200px 200px;
// Change values ???? to experiment
justify-items : end;
}
Свойство align-items
Свойство позиционирует дочерние элементы сетки внутри контейнера вдоль оси Y.
Возможны следующие 4 значения.
Не изменяйте ничего в HTML, но в CSS напишите:
.container {
display: grid;
gap: 50px;
height: 100vh;
// each box is 200px by 200px
grid-template-rows: 200px 200px;
grid-template-columns: 200px 200px;
// Change values ???? to experiment
align-items: center;
}
Свойство justify-content
Свойство позиционирует всю сетку внутри контейнера вдоль оси X. Имеется 7 значений.
Не изменяйте ничего в HTML, но в CSS напишите:
.container {
display: grid;
gap: 50px;
height: 100vh;
// each box is 200px by 200px
grid-template-rows: 200px 200px;
grid-template-columns: 200px 200px;
// Change values ???? to experiment
justify-content: center;
}
Свойство align-content
Свойство позиционирует всю сетку внутри контейнера вдоль оси Y. Имеется 7 значений.
Не изменяйте ничего в HTML, но в CSS напишите:
.container {
display: grid;
gap: 50px;
height: 100vh;
// each box is 200px by 200px
grid-template-rows: 200px 200px;
grid-template-columns: 200px 200px;
// Change values ???? to experiment
align-content : center;
}
Свойства дочерних элементов сетки CSS
Теперь давайте рассмотрим дочерние свойства Grid.
Масштаб сетки CSS
Сделаем схему сетки. Она нужна, чтобы показать, как рассчитать соединение строк и столбцов. Для расчётов мы можем использовать любой их двух типов измерения:
- Цифру — 1, 2, 3, 4 и т.д.
- Ключевое слово span.
Совсем скоро вы поймёте, как работает это руководство.
На рисунке ниже показаны начальные и конечные точки строк и столбцов одной сетки.
HTML
Чтобы поэкспериментировать с масштабом сетки и понять дочерние свойства, создайте четыре бокса внутри тега body
:
<div class="container">
<div class="box-1"> A </div>
<div class="box-2"> B </div>
<div class="box-3"> C </div>
<div class="box-4"> D </div>
</div>
Используем функцию repeat()
. Она повторяет наш код определенное количество раз. Вот пример:
grid-template-columns : repeat(5,1fr);
Это эквивалентно написанию следующего:
grid-template-columns : 1fr 1fr 1fr 1fr 1fr ;
Когда мы используем единицу fr
(дробное число), мы делим экран на равные части.
grid-template-columns: repeat(5, 1fr);
Этот код делит наш экран на 5 равных столбцов.
Мы готовы, давайте начнем!
Grid-column: свойства start и end
Эти два свойства используются для объединения нескольких колонок. Это сокращение двух свойств:
- grid-column-start;
- grid-column-end.
Напишите этот код в CSS:
.container {
display: grid;
gap: 20px;
height: 100vh;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: repeat(12, 1fr);
}
Результат выглядит следующим образом:
Здесь мы делим наш экран — как по ширине, так и по высоте — на 12 равных частей.
Одна ячейка занимает одну часть или одну дробь 1fr
. Остальные 8 ячеек пусты.
Поскольку мы имеем дело с дочерними свойствами, нам нужно нацелить наши классы .box-*
следующим образом:
.box-1{}
.box-2{}
.box-3{}
.box-4{}
Вы можете экспериментировать с любыми ячейками, я буду использовать .box-1
.
Зададим масштаб нашей сетке. Пока мы имеем дело только с колонками, а не со строками.
Масштаб по умолчанию для каждого класса .box-*
:
grid-column-start : 1;
grid-column-end : 2;
/* The shorthand -> */
grid-column : 1 / 2
Мы можем записать это в единице измерения span
:
grid-column : span 1;
Добавим пустые 8 колонок в .box-1
вот так:
.box-1{
grid-column : 1/10
}
Результат выглядит следующим образом:
Как вышло, что нам нужны 8 колонок, а мы записываем 10?
Box-1
сам по себе занимает 1 блок. И поверх него мы добавляем еще 8 блоков. Кроме того, нам нужно добавить ещё один, чтобы обозначить конец, так что 8+1+1+1 = 10
.
Если вам сложно понять, как это работает, используйте span
, оно проще для понимания.
В span
нужно добавить 8 ячеек к .box-1
, который уже занимает одну ячейку. Таким образом, получится 8+1 = 9
.
.box-1{
grid-column : span 9;
}
Это приведет к тому же результату.
Свойства grid-row: start/end
Эти два свойства используются для объединения нескольких строк.
Это сокращение двух свойств:
- grid-row-start;
- grid-row-end.
Здесь мы будем использовать .box-1
. Теперь сосредоточимся только на строках, а не столбцах.
Добавим 9 блоков к .box-1
вдоль строки.
Напишите этот код:
.box-1{
grid-row : 1/11;
}
Расчет выглядит следующим образом: .box-1
вмещает 1 блок, и вы добавляете еще 9 блоков, плюс обязательная 1 в конце. Получается 9+1+1=11
.
Вот альтернатива с использованием span
:
.box-1{
grid-row : span 10;
}
Здесь .box-1
вмещает один блок, и вы добавляете еще 9 блоков. Получается 9+1=10
.
Вот результат:
Свойство grid-area
Для него сперва нужно настроить grid-template-areas
. После этого нужно указать имена родительских классов в дочерних классах:
Затем нужно настроить grid-template-areas
внутри родительского контейнера:
.container {
display: grid;
gap: 20px;
height: 100vh;
grid-template-areas:
"A A A A A A A A A A A A"
"B B B B B B B B B B C C"
"B B B B B B B B B B C C";
}
Затем укажем имена родительских контейнеров внутри дочерних классов с помощью grid-areas
.
.box-1{
grid-area: A;
}
.box-2{
grid-area: B;
}
.box-3{
grid-area: C;
}
Свойство justify-self
Это свойство используется для позиционирования одного дочернего элемента сетки внутри контейнера вдоль оси X. Есть 4 значения.
Напишите этот код, чтобы поэкспериментировать со значениями:
.container {
display: grid;
gap :25px;
height: 100vh;
/* // each box has equal size */
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
Помните, что свойство действует только на дочерние классы.
Итак, выберите любой класс .box-*
. Мы покажем пример на первом блоке:
.box-1 {
/* Change values ???? to experiment */
justify-self : start;
}
Свойство align-self
Свойство используется для позиционирования одного дочернего элемента сетки внутри контейнера вдоль оси Y. Есть 4 значения.
Поэкспериментируем со значениями:
.container {
display: grid;
gap :25px;
height: 100vh;
/* // each box has equal size */
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
Помните! Свойство действует только на дочерние классы. Выберите любой класс .box-*
. Мы используем первый бокс:
.box-1 {
/* Change values ???? to experiment */
align-self : start;
}
Сокращение для свойств сетки CSS
Давайте рассмотрим сокращенные свойства Grid:
- place-content;
- place-items;
- place-self;
- grid-template;
- gap / grid-gap.
place-content
Это сокращенное обозначение двух свойств:
- align-content;
- justify-content.
align-content : center;
justify-content : end;
/* The shorthand */
place-content : center / end ;
place-items
Это сокращенное обозначение двух свойств:
- align-items;
- justify-items.
align-items : end;
justify-items : center;
/* The shorthand */
place-items : end / center ;
place-self
Это сокращенное обозначение двух свойств:
- align-self;
- justify-self.
align-self : start ;
justify-self : end ;
/* The shorthand */
place-self : start / end ;
grid-template
Это сокращенное обозначение двух свойств:
- grid-template-rows;
- grid-template-columns.
grid-template-rows : 100px 100px;
grid-template-columns : 200px 200px;
/* The shorthand */
grid-template : 100px 100px / 200px 200px;
gap/grid-gap
Gap и grid-gap — это одно и то же сокращение. Вы можете использовать любое из них.
Это сокращенное обозначение двух свойств:
- row-gap;
- column-gap.
row-gap : 20px ;
column-gap : 30px ;
/* The shorthand */
gap : 20px 30px;
Заключение
Теперь вы можете уверенно делать отзывчивые макеты сайтов, используя знания о сетке!
Спасибо за то, что вы дочитали до конца.
Мы давно изучали CSS-гриды, сами и вместе с зарубежными авторами. Тогда же возникла мысль оформить результат в виде подробного руководства по ним, вроде этого по флексбоксам. Это оказалось не так-то просто: стандарт большой, вводит множество новых понятий, к тому же эти понятия переплетены друг с другом, совсем как полосы самих гридов (как показать грид-области без привязанных к ним грид-элементов, и наоборот?). Поэтому работа над статьей, скажем прямо, несколько затянулась:) Но теперь, когда грид-раскладка уже поддерживается почти повсеместно (Firefox 52+, Chrome 57+, Opera 44+, Safari 10.1+/iOS 10.3+ Safari, Яндекс-Браузер 17+, а также в Android WebView), мы рады представить вам результат трудов. Надеемся, он поможет разобраться в горах новых возможностей. Это не «полное руководство» (полностью описать все возможности CSS Grid в одной статье просто нереально!), но мы постарались упомянуть некоторые важные моменты, упущенные многими из «полных руководств». Любые дополнения и уточнения приветствуются!
Краткое содержание:
- Основа и терминология
- Грид-контейнер и его свойства
- Создание грид-контейнера
- Разметка колонок и рядов
- Размеры грид-полос
- Имена грид-линий
- Функция
repeat()
- Разметка грид-областей
- Сокращенная запись для колонок, рядов и областей
- Неявный грид (автоматические ряды и колонки)
- Алгоритм авторазмещения элементов в контейнере
- Одно свойство, чтоб править всеми: grid
- Промежутки между ячейками (грид-интервалы)
- Выравнивание и центрирование грид-полос в грид-контейнере
- Грид-элементы и их свойства
- Привязка грид-элемента к грид-линиям
- По номеру
- По имени
- По имени и номеру
- Сокращенные свойства
- Размещение грид-элемента в грид-области
- Автоматическое размещение грид-элементов
- Порядок грид-элементов
- Выравнивание и центрирование грид-элемента в грид-области
- Наложение грид-элементов
- Привязка грид-элемента к грид-линиям
- Песочницы
Основа и терминология
Грид — это двумерная (в отличие от от одномерных флексбоксов) сетка. Как табличная, только виртуальная, не связанная с разметкой. Состоит из следующих элементов:
- Грид-контейнер — элемент, в котором строится сетка.
- Грид-элементы — элементы, размещаемые по сетке. Важно: они должны быть непосредственными потомками грид-контейнера (как и во флексбоксах флекс-элементы должны быть непосредственными потомками флекс-контейнера).
- Грид-линии — невидимые вертикальные и горизонтальные линии, разделяющие грид на ячейки и формирующие его структуру. Грид-линии автоматически нумеруются, а также им можно задавать имена. К грид-линиям можно привязывать грид-элементы — и по номерам, и по именам, как удобнее.
- Грид-полосы — то, что ограничено парой соседних грид-линий. Вертикальные грид-полосы — это колонки грида (аналог столбцов таблицы), горизонтальные — ряды (аналог строк).
- Грид-ячейки — то, что получается на пересечении двух грид-полос (колонки и ряда). Аналог ячейки таблицы.
- Грид-области — прямоугольники из M×N смежных грид-ячеек (1×1 и больше). Каждая грид-область ограничена двумя парами грид-линий (парой вертикальных и парой горизонтальных). В них и размещаются грид-элементы. Грид-областям тоже можно задавать имена.
- Грид-интервалы — пустые пространства (отступы) между соседними грид-полосами. Аналог
border-spacing
в таблице.
See the Pen LypJVK by Ilya Streltsyn (@SelenIT) on CodePen.
Ограничение, что грид-элементы должны быть непосредственными потомками грид-контейнера, в будущем снимут подсетки (subgrids). Пока их нет, его можно частично обойти с помощью display:contents
или эмулировать CSS-переменными.
Визуализировать грид-линии умеет отладчик Firefox (иконка в виде решетки, указанная стрелкой):
Примечание: простой текст (всё, кроме пробелов, табов и переводов строк), оказавшийся непосредственно в грид-контейнере (между тегами), оборачивается в анонимные грид-элементы. Подобный эффект нам уже знаком по флексбоксам.
Грид-контейнер и его свойства
Создание грид-контейнера
Задаем ему display:grid
. Или display: inline-grid
, разница с обычным grid
такая же, как у inline-block
с block
. Ниже наглядный пример:
See the Pen Kzvrrw by Ilya Streltsyn (@SelenIT) on CodePen.
Разметка колонок и рядов
Используем свойства grid-template-rows
и grid-template-columns
.
Значения этих свойств состоят из перечисления размеров грид-полос (через пробел). До и после размера полосы можно указывать имена грид-линий, в квадратных скобках. Чтобы не писать одно и то же по нескольку раз, можно сократить запись функцией repeat()
. Подробности ниже.
Размеры грид-полос
Размер каждой грид-полосы (ширину колонки/высоту ряда) можно задавать:
- В любых CSS-единицах длины, абсолютных (pt, mm, px…) или относительных (em, rem, vw, vh…).
- В процентах (от доступной ширины или указанной высоты грид-контейнера — как для блоков).
- В единицах
fr
(от fraction — часть). Свободное место распределяется между такими полосами пропорционально количествуfr
. Как наflex-grow
у флексбоксов (при нулевомflex-basis
). - Ключевым словом
min-content
— наименьший возможный размер контента. Для текста это ширина самого длинного неразрываемого фрагмента или слова. - Ключевым словом
max-content
— наибольший размер контента. Для текста это длина самой большой строки без переносов. - Функцией
minmax(<минимум>, <максимум>)
. Задает минимум, до которого можно ужимать полосу, и максимум, на который она может растянуться, если хватит места (аналог min/max-width или min/max-height в одной записи). Максимум можно задавать всеми вышеперечисленными способами, минимум — всеми, кроме fr. Обычно минимум делают фиксированным, а максимум — гибким, напр.minmax(200px, 30%)
илиminmax(5em, 2fr)
. Подробнее о ней здесь. - Ключевым словом
auto
— размер грид-полосы подстраивается под размеры ее грид-элементов, так, чтобы самый большой из них уместился впритык. Не дает грид-полосе ужиматься меньшеmin-width
самого широкого грид-элемента (для колонки) илиmin-height
самого высокого (для ряда) и растягиваться больше, чемmax-content
. Но есть важный нюанс: грид-полосы с размеромauto
могут растягиваться при*-content: stretch
(и отсутствии других полос с размерами воfr
). - Функцией
fit-content()
с максимальным размером в качестве параметра. Если контент не больше этого размера, ведет себя как auto, если больше — этот параметр становится размером полосы. Что делать, если указан размер меньше самого длинного слова (т.е.min-content
), браузеры пока не определились.
Примечание: на момент публикации статьи min-content
и max-content
в Safari требуют префикса -webkit-. Именно для значения, не для свойства. А вот в Firefox они работают без префикса (хотя MDN и caniuse опять это скрывают!).
Пример действия разных значений:
.grid { display: grid; grid-template-columns: 50px 20% min-content max-content 1fr 2fr auto; grid-template-rows: auto minmax(50px, 50vh) 4em; /* другие свойства... */ }
See the Pen ZWJmzg by Ilya Streltsyn (@SelenIT) on CodePen.
Обратите внимание, что при уменьшении грид-контейнера последняя колонка и последний ряд выходят за его край, так как сумма размеров грид-полос становится больше размера контейнера. Это нормальное поведение.
Также обратите внимание, что при увеличении размеров контейнера ряд с размером auto
начинает растягиваться по высоте. А колонка с размером auto
не растягивается, потому что есть другие колонки с гибким размером (fr
). Если бы их не было, колонка с auto
бы тоже растягивалась.
(Добавлено 13.07.2017): и еще обратите внимание, что полосы с размерами в fr
не сжимаются меньше наименьшего размера контента, т.е. фактически ограничены снизу значением min-content
. Так что широкий контент (таблица, большая картинка и т.п.) может «распереть» колонку и визуально нарушить структуру грида (автор примера сам было попался:). Если нужно, чтобы колонка сужалась сильнее, указывайте минимум явно, например, minmax(0%, 1fr)
.
Имена грид-линий
Удобны для привязки грид-элементов к ним. Пишутся в квадратных скобках перед или после размера соотв. полосы. У одной грид-линии может быть много имен. Имена грид-линий могут быть практически любыми — как имена классов. Допустимы русские буквы и др. символы юникода, даже эмодзи (но чувствуйте меру:).
.grid { /* другие свойства... */ grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom]; }
У каждой грид-линии, именованной или нет, есть также два номера: с начала грида, положительное число (1, 2, 3, …), и с конца грида, отрицательное число (-1, −2, −3, …). Привязывать грид-элементы к ним можно как по именам, так и по любому из этих номеров.
Больше примеров и подробностей — в отдельной статье.
У имен грид-линий, оканчивающихся на -start и -end, есть своя «особая магия»: они косвенно создают именованные грид-области (см. подробности в разделе о них).
Функция repeat()
Общий синтаксис: repeat(<сколько раз повторять>, <что повторять>)
. У нее два основных варианта:
- Повторение любой последовательности грид-полос указанное число раз.
- Повторение одной грид-полосы до заполнения грид-контейнера по соответствующей оси. Количество повторов задается ключевым словом
auto-fill
либоauto-fit
:auto-fill
повторяет грид-полосу столько раз, сколько вместится в размер грид-контейнера. Если у грид-контейнера задан максимальный размер, грид-полоса повторяется столько раз, сколько вместится без переполнения (если без переполнения никак не вмещается — то один раз). Если у грид-контейнера задан только минимальный размер, грид-полоса повторяется столько раз, сколько достаточно для превышения этого минимума. Хотя бы одно повторение будет в любом случае.auto-fit
— то же самое, но после размещения грид-элементов оставшиеся пустыми грид-полосы сжимаются до нуля, а интервалы между ними объединяются в один интервал. Т.е. пустые полосы как будто выбрасываются. Если полос вмещается пять, но элемента только три — в итоге и полос будет только три.
Есть несколько важных ограничений:
- Нельзя вкладывать
repeat
в другойrepeat
. - С
auto-fill
иauto-fit
можно повторять только конкретные размеры. Явно заданные (в единицах длины или процентах) или хотя бы явно ограниченные с одной стороны, но не*-content
, неfr
и неauto
.repeat(auto-fill, 100px)
— можноrepeat(auto-fit, minmax(100px, 1fr))
— можноrepeat(auto-fill, auto)
— нельзяrepeat(auto-fit, 1fr)
— нельзя
repeat
cauto-fill
илиauto-fit
может быть только один на одно свойство (grid-template-rows
илиgrid-template-columns
).grid-template-columns: repeat(3, 50px 5%) repeat(auto-fill, 100px) repeat(4, 80px)
— можноgrid-template-columns: repeat(auto-fill, 50px) repeat(2, 100px) repeat(auto-fit, 80px)
— нельзя (2repeat
с неизвестным количеством повторений)
- Если есть
repeat
cauto-fill
илиauto-fit
, то в остальныхrepeat
для этого же свойства тоже можно повторять только конкретные размеры (не*-content
, неfr
и неauto
).grid-template-columns: repeat(2, 2fr) repeat(4, 1fr)
— можно (нетauto-fill
/auto-fit
)grid-template-columns: repeat(4, 10%) repeat(auto-fill, 10em)
— можно (в первомrepeat
повторяется конкретная ширина в процентах)grid-template-columns: repeat(auto-fill, 100px) repeat(4, 1fr)
— нельзя (в одномrepeat
естьauto-fill
, а в другомrepeat
повторяется заранее неизвестная ширина).
С auto-fill
легко решается старая задача выравнивания одинаковых блоков по резиновой сетке.
Разметка грид-областей
Используем свойство grid-template-areas (известное как «разметка страницы ASCII-графикой»). Каждая строка значения задает имена ячейкам соответствующего ряда, повторение одного и того же имени указывает, что грид-область с таким именем охватывает несколько ячеек. Имена грид-областей, как и грид-линий, могут быть любыми (хоть эмодзи), кроме ключевых слов CSS. Неиспользуемые (пропускаемые) ячейки обозначаются точкой:
#grid { display: grid; grid-template-areas: "head head" "nav main" "foot . "; }
В эти области можно напрямую помещать грид-элементы.
Несколько пробелов между именами считаются за один, поэтому можно добавлять их сколько угодно для красоты и наглядности. А можно не добавлять: grid-template-areas: "head head" "nav main" "foot .";
— то же самое, что пример выше.
При создании грид-области с именем что-то ограничивающие ее грид-линии получают имена что-то-start и что-то-end. И наоборот: пара параллельных грид-линий с именами что-то-start и что-то-end автоматически создает между собой именованную грид-область с именем что-то.
Можно указывать одновременно и размеры, и grid-template-areas
:
.grid { display: grid; /* другие свойства: размеры и т.п. */ grid-template-columns: 2fr 1fr; grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom]; grid-template-areas: "banner banner" "container menu"; }
See the Pen GmJVPO by Ilya Streltsyn (@SelenIT) on CodePen.
Сокращенная запись для колонок, рядов и областей: grid-template
Более короткий (но менее понятный) способ указывать грид-области и размеры грид-полос одновременно: свойство grid-template
.
Вот предыдущий пример, переписанный на grid-template
и отформатированный для максимальной наглядности (посмотреть вживую):
.grid { display: grid; /* другие свойства: размеры и т.п. */ grid-template: [header-top] /* верхняя горизонтальная грид-линия */ "banner banner" auto /* структура первого ряда и его высота */ [header-bottom main-top] /* средняя горизонтальная грид-линия */ "container menu" 1fr /* структура второго ряда и его высота */ [main-bottom] /* нижняя горизонтальная грид-линия */ / /* конец описания рядов */ 2fr 1fr; /* ширины грид-колонок */ } }
Важно: в такой записи (сочетание «ASCII-графики» с размерами) нельзя использовать repeat()
, потому что перечисления рядов/колонок должны визуально соответствовать именам областей в «ASCII-графике».
Неявный грид (автоматические ряды и колонки)
При попытке разместить грид-элемент за пределами явных грид-полос автоматически генерируются неявные полосы. Их размерами можно управлять с помощью grid-auto-rows
и grid-auto-columns
. По умолчанию они auto
(грубо говоря, по контенту, см. «Размеры грид-полос»).
Неявные полосы могут генерироваться как перед явными, так и после них. Соответствующие грид-линии продолжают нумерацию: после грида — положительную, перед гридом — отрицательную. Чем-то похоже на то, как добавляются дополнительные линейки для нот, оказавшихся выше или ниже основных пяти линеек. Вот пример грида с 5 явными линиями для рядов (т.е. 4 рядами) и несколькими «нотами», привязанными (с помощью grid-row-start
, о нем чуть ниже) к линиям как в пределах явного грида, так и за его пределами:
See the Pen OpKzxK by Ilya Streltsyn (@SelenIT) on CodePen.
Важный момент: грид-линия № 1 не всегда совпадает с началом грид-контейнера! Браузер пытается уместить в грид-контейнер весь грид, не только явные полосы. Поскольку по умолчанию грид-полосы выравниваются по началу грид-контейнера, неявные грид-полосы будут выталкивать явные вниз (для рядов) или вправо (для колонок, для текста слева направо). В этом примере, благодаря тому, что общая ширина неявных полос сверху и снизу одинакова, можно подогнать явные ряды к границам грид-контейнера, отцентрировав весь грид по вертикали (с помощью align-content: center
). Можете поменять align-content
у грид-контейнера и увидеть эту разницу (контейнер при наведении подсвечивается). Но такое везение бывает не всегда!
Для привычного нам размещения «текст слева направо, строчки сверху вниз», если элемент оказывается за пределами колонок грида — чаще всего это ошибка (хотя может быть и дизайнерским приемом). А вот создавать ряды автоматически по мере необходимости, продолжая грид вниз, бывает нужно сплошь и рядом.
Алгоритм авторазмещения: направление и «плотность упаковки» элементов
Еще одна аналогия с флексбоксами: у флекс-контейнера есть свойство flex-flow
, указывающее, как пойдут элементы в нем — по вертикали или по горизонтали. У грид-контейнера есть очень похожее: grid-auto-flow
. И первая часть значения та же самая: row
либо column
. Т.е. обходить ячейки по строкам (по умолчанию слева направо) либо по столбцам (сверху вниз).
У второй, необязательной, части значения аналога нет. Ключевое слово dense
указывает, что надо «запихивать» элементы в грид как можно плотнее, по возможности заполняя каждую ячейку. По умолчанию, без dense
, алгоритм авторазмещения «высматривает» подходящее для очередного элемента место только «впереди», не оглядываясь на уже пройденные строки/столбцы.
Примеры различия «с dense
и без» есть в одной из первых статей о CSS-гридах в Рунете на css-live, а также в недавней статье. Еще немного подробностей будет ниже, в разделе про сами грид-элементы. Ну и совсем простенький наглядный пример всех 4 вариантов значений:
See the Pen LLxMjX by Ilya Streltsyn (@SelenIT) on CodePen.
Одно свойство, чтоб править всеми: grid
Способ указывать и грид области, и размеры всех грид-полос — явных и неявных, и алгоритм авторазмещения, всё сразу. Поэтому еще более запутанный, чем grid-template. И может принимать те же значения, что и grid-template (тогда неявные полосы и алгоритм авторазмещения будут по умолчанию, auto
и row
соответственно). Но очень удобен в простых случаях. Например, просто и быстро поделить контейнер на 4 колонки и 3 ряда:
grid: repeat(4, 1fr) / repeat(3, 1fr); /* ...и готово! */
Но вообще это свойство заслуживает отдельной статьи. Мы постараемся разобрать его в ближайшее время.
Промежутки между ячейками (грид-интервалы)
Делаются специальными свойствами grid-row-gap
и grid-column-gap
, либо сокращенным свойством grid-gap
:
grid-row-gap: 5px; grid-column-gap: 10%; /* или, короче */ grid-gap: 5px 10%;
Если задать grid-gap
одно значение, отступы между рядами и колонками будут равными:
grid-gap: 5px; /* то же, что и grid-gap: 5px 5px; */
В общем, почти как border-spacing
для таблиц. Только бывает еще и в процентах. И добавляется только между полосами, снаружи крайних полос не добавляется.
Неинтуитивный момент: начало и конец грид-интервала считаются одной и той же грид-линией (этакая толстая линия, во весь интервал толщиной:). Можете еще раз посмотреть на это в первом примере (про терминологию).
Выравнивание и центрирование грид-полос в грид-контейнере
Если грид-полосы заполняют грид-контейнер не целиком (т.е. сумма их размеров меньше размера грид-контейнера и нет полос с размерами во fr
), оставшееся свободное место может быть перед ними, после них, вокруг них и между ними. Делается свойствами justify-content
/align-content
. Общий принцип тот же, что у выравнивания строк в многострочном флекс-контейнере. Подробнее об этих свойствах — в отдельной статье.
Можно посмотреть это на живом примере:
See the Pen dWYjKr by Ilya Streltsyn (@SelenIT) on CodePen.
При space-between
, space-around
и новом значении space-evenly
фактически растягиваются грид-интервалы (это уточнение появилось в спецификации благодаря статье на css-live.ru:).
Грид-элементы и их свойства
О способах размещения грид-элементов есть отдельная подробная статья одного из авторов реализации гридов в Chrome и Safari, с прекрасными иллюстрациями. Добавить к ней что-то новое сложно. Так что просто кратко перечислим, какие возможности есть.
Привязка грид-элемента к грид-линиям
Используем 4 свойства:
grid-row-start
grid-row-end
grid-column-start
grid-column-end
По умолчанию у них значение auto
(находить место для элементов автоматически, об этом ниже). Можно привязывать элементы к грид-линиям по номеру (любому из двух — положительному, с начала, или отрицательному, с конца), по имени, по имени и номеру (если одноименных линий несколько, например, при repeat). Бегло рассмотрим все три способа.
По номеру
Например, grid-row-start: 3; grid-row-end: 5
— поставить элемент между 3-й и 5-й линиями рядов (т.е. он будет занимать два ряда, 3-й и 4-й). То же самое — grid-row-start: 3; grid-row-end: span 2
(от третьей линии до второй по счету линии после начальной). Или grid-row-start: span 2; grid-row-end: 5
(от второй по счету линии перед конечной до пятой линии).
Еще пример: grid-column-start: -5; grid-column-end: -2 — поставить элемент между 5-й и 2-й линиями колонок с конца (т.е. он займет 3 колонки, 4-ю от конца явного грида, 3-ю от конца и предпоследнюю). Это то же самое, что grid-column-start: -2; grid-column-end: -5 (если начало позже конца, они меняются местами). А вот grid-column-start: -2; grid-column-end: span -3 сделать нельзя: span может быть только положительным. Записать «от третьей линии перед второй с конца до второй с конца» можно только так: grid-column-start: span 3; grid-column-end: -2. А растянуть элемент на всю ширину грида, от начала до конца, можно так: grid-column-start: 1; grid-column-end: -1.
Это работает и с линиями неявного грида, только номер у них лишь один (у добавочных линий перед гридом — только отрицательный, у добавочных после — только положительный).
Примечание: во многих руководствах (и даже в нескольких местах спецификации!) говорится, что span
указывает, сколько грид-полос занимает элемент. Для привязки по номерам линий это верно (и может быть даже нагляднее), но с именованными линиями это уже не так (см. ниже). На мой взгляд, надежнее всегда считать именно линии, с ними точно не запутаетесь.
По имени
Например, grid-row-start: header; grid-row-end: abracadabra. И даже grid-row-start: ? ?; grid-row-end: ? ?
(кому удобнее обозначать предметы «современными иероглифами», идея из статьи Юны Кравец). Лично меня больше запутывают не эмодзи, а названия, совпадающие с ключевыми словами CSS (когда я после долгого перерыва стал заново разбирать статью Мануэля, до меня не сразу дошло, что grid-row-start: top и grid-column-end: right — не какие-то специальные режимы, а просто названия линий:). Но по стандарту называть линии можно как угодно, так что делайте, как удобнее вам и вашим коллегам!
Запись grid-row-end: span sidebar означает «охватить ряды вплоть до линии с именем sidebar» (если таких линий несколько — то до ближайшей из них, см. ниже).
По имени и номеру
При повторяющейся структуре грида может быть несколько линий с одинаковым именем (пример этого тоже был в раннем цикле статей про CSS Grid). Чтобы привязаться к одной конкретной из них, указываем и имя, и номер: grid-column-start: content 3 — началом элемента будет 3-я по счету линия с именем content. Чуть ниже вы можете увидеть это в деле в сокращенной записи.
Фактически, «массив» именованных линий создается всегда, даже для единственной линии, и обращение к линии по имени без номера — это обращение к первой линии из этого «массива» (grid-row-end: abracadabra — то же самое, что grid-row-end: abracadabra 1, пропущенный номер линии по стандарту интерпретируется как 1).
Сокращенные свойства
Пары grid-*-start
и grid-*-end
можно писать сокращенно — как grid-row
и grid-column
соответственно. Значение записывается через слеш (до слеша *-start
, после него *-end
):
grid-row: 2 / 4; // от 2-й до 4-й линий, т.е. 2-й и 3-й ряды grid-column: span 3 / -2; // 3 колонки до предпоследней включительно grid-column: menu-end / span item-column 2; // от конца области menu до 2-й линии с именем "item-column"
Если указано только одно значение, оно считается начальным, а конечное обычно подставляется по умолчанию (span 1
— до следующей линии после указанной, т.е. занять 1 полосу). Но если в структуре грида есть линии что-то-start
и что-то-end
(или, что то же самое, есть грид-область что-то
), то включается «магия» этих имен: grid-row: что-то
превращается в grid-row: что-то-start / что-то-end
(для grid-column
аналогично). Не очень очевидно, но очень удобно! В примере ниже banner
и menu
— «волшебные» имена, а content
(их 3 шт.) — обычные (хотя геометрически первая из них совпадает с banner-start
):
See the Pen jwVNMQ by Ilya Streltsyn (@SelenIT) on CodePen.
Можно написать еще короче, сократив обе пары сразу: grid-area
. У него может быть от 1 до 4 значений, тоже через слеш.
Если есть все 4 значения, их порядок такой: grid-row-start / grid-column-start / grid-row-end / grid-column-end. Т.е., для текста слева направа — против часовой стрелки (в отличие от сокращенных записей для margin, padding, border-* и большинства прочих свойств с 4 сторонами)! Пожалуй, чтобы не запутаться, лучше запоминать порядок не «верх/лево/низ/право», а именно как начала и концы ряда и колонки соответственно.
Если части grid-row-end/grid-column-end пропущены, для них работает та же логика, что для grid-row
и grid-column
: если значение для соотв. начальной линии — «волшебное» имя, оно разворачивается в пару что-то-start
и что-то-end
, если нет — для конечной линии подставляется auto
. Если же указано всего одно значение что-то, то если грид-область с таким именем есть — оно разворачивается в четверку свойств со значениями что-то-start
и что-то-end
, привязывающих элемент к грид-области с таким именем. А если нет — все 3 недостающие части становятся auto
.
Размещение грид-элемента в грид-области
Здесь и пригодится grid-area
с одним значением — именем грид-области. Неважно, присвоено ей это имя прямо (в свойстве grid-template-areas для грид-контейнера)…
#grid0 { display: grid; grid-template-areas: "head head" "nav main" "foot . "; } #grid0 > header { grid-area: head; } #grid0 > nav { grid-area: nav; } #grid0 > main { grid-area: main; } #grid0 > footer { grid-area: foot; }
…или косвенно (парой вертикальных и парой горизонтальных «волшебных» грид-линий с окончаниями -start/-end):
#grid1 { display: grid; grid-template-columns: [head-start nav-start foot-start] auto [nav-end foot-end main-start] auto [head-end main-end]; grid-template-rows: [head-start] auto [head-end nav-start main-start] auto [nav-end main-end foot-start] auto [foot-end]; } #grid1 > header { grid-area: head; } #grid1 > nav { grid-area: nav; } #grid1 > main { grid-area: main; } #grid1 > footer { grid-area: foot; }
Результат от способа задания имени грид области (слева — прямое, справа — косвенное), как видно в примере ниже, не зависит:
See the Pen JNpXom by Ilya Streltsyn (@SelenIT) on CodePen.
Автоматическое размещение грид-элементов
По умолчанию грид-элементы размещаются по одному, каждый следующий занимает ближайшую следующую свободную грид-область из достаточного количества грид-ячеек. Направление, в котором алгоритм ищет эту следующую область, определяется свойством grid-auto-flow
контейнера.
При знакомстве с автоматическим размещением с плотной упаковкой (dense), наверное, у каждого верстальщика возникает мысль: «Что, теперь не нужны скрипты типа Masonry, и раскладку а-ля Pinterest можно делать чистым CSSом?». Увы: совсем заменить Masonry гриды пока не могут. Грид-элементы пока не умеют автоматически охватывать столько полос, сколько нужно, чтобы вместить их контент: ведь размеры полос сами могут зависеть от размеров элементов, и получается бич CSS — циклическая зависимость (обновлено 1.08.2021: вариант решения этой проблемы внесен в следующий уровень спецификации). Но мы можем расставить их динамически! Хотя бы простейшим скриптом, как в примере ниже (форке одного из примеров к самому Masonry):
See the Pen Masonry (fluid columnWidth) with CSS Grid by Ilya Streltsyn (@SelenIT) on CodePen.
Откройте его в отдельной вкладке и посмотрите, что происходит при ресайзе окна. Вся логика скрипта заняла немногим больше строчек, чем одно лишь подключение Masonry в оригинале!
Важное замечание: но всё же не стоит слишком увлекаться таким приемом для очень длинных страниц, особенно с «бесконечным скроллингом». Максимальное количество рядов в гридах в браузерах ограничено, если их станет больше 1000 — могут быть проблемы.
Порядок грид-элементов
При явной привязке грид-элементов к линиям и/или областям их порядок значения не имеет. Куда что поставите, там то и будет. Порядок влияет только на наложение грид-элементов, если их грид-области пересекаются (см. ниже).
При автоматическом размещении элементы идут в том порядке, как они идут в разметке. Это можно изменить тем же свойством order
, что во флексбоксах. Работает оно тут практически так же. Но не злоупотребляйте им: разный порядок на экране и при клавиатурной навигации считается проблемой доступности.
Выравнивание и центрирование грид-элемента в грид-области
Грид-элементы можно выравнивать (в т.ч. центрировать) в своих грид-ячейках или грид-областях всеми свойствами для выравнивания (из модуля CSS Box Alignment). Используются свойства justify-items/align-items для контейнера (выравнивают все элементы сразу) или justify-self/align-self для самого элемента (выравнивает конкретно его), во многом аналогично выравниванию флекс-элементов во флекс-контейнере. Подробнее о них — в отдельной статье. Можно поиграть с ними и в живом примере:
See the Pen GmKMyp by Ilya Streltsyn (@SelenIT) on CodePen.
По умолчанию, если ничего не делать, грид-элементы растягиваются (stretch
) на всю область по обеим осям. Наверное, чаще всего именно это и нужно.
Наложение грид-элементов
Если несколько грид-элементов размещены в одной грид-области/ячейке, они могут накладываться друг на друга. Порядком наложения можно управлять с помощью z-index
— совсем как для позиционированных элементов.
Вы могли заметить это в самом первом примере в статье, при наведении на термины вверху (можно вернуться и посмотреть еще раз:).
Песочницы
Любую новую технологию проще осваивать «методом тыка», на удобном тренажере. Но сделать свою «песочницу» для гридов по образцу «песочницы» для флексбоксов из визуального руководства по ним оказалось не так-то просто: в гридах, в отличие от флексбоксов, грид-области существуют независимо от грид-элементов, так что их нужно визуализировать отдельно. Возможно, то, что получилось, тоже окажется для вас чем-то полезным (особенно в сочетании с грид-инспектором из отладчика Firefox), но хочется большего (напр. наглядного визуального редактора структуры грида). Мы работаем над этим, так что следите за обновлениями сайта!:)
А пока, кроме вышеприведенной ссылки, «потыкать» гриды можно с помощью следующих ресурсов:
- Песочница по гридам Мирзы Джолдика. Простой, но наглядный инструмент с текстовым интерфейсом: есть поле для ввода CSS-кода грид-контейнера, поле для общего CSS-кода всех грид-элементов, а прямо в каждый из самих элементов можно вводить его «персональный» CSS-код. Элементы можно добавлять и удалять, а также скрывать/показывать их порядковый номер и примененные стили. Благодаря тому, что стили задаются напрямую CSS-кодом, тут нет типичных для подобных песочниц ограничений (напр., можно вовсю использовать автоматические полосы и
repeat
), но нужно знать, что вводить (совсем начинающим может быть сложновато). У автора песочницы есть также неплохая статья по гридам с примерами ее использования. И эту песочницу рекомендовала сама Джен Симмонс:) - Шпаргалка по гридам Али Алаа. Тут, наоборот, яркий (даже очень:) и наглядный GUI, так что добавить/удалить ряд/колонку грида или изменить их размер — и тут же посмотреть, что получится — можно буквально в один клик. Грид-элементы тоже можно динамически добавлять, а по клику на элемент выезжает дополнительная панель инструментов, где можно изменить его свойства (перепривязать к другим грид-линиям и изменить выранивание). Но оборотная сторона наглядности интерфейса — некоторые продвинутые функции (
repeat
сauto-fill
/auto-fit
, именованные области и т.д.) недоступны. - Визуальный редактор grid-template Энтони Дюгуа. Удачный «гибрид» визуального и текстового интерфейсов: управлять струтурой грид-областей можно как редактированием CSS-кода, так и перетягиванием прямоугольников по нарисованной сетке, когда что-то одно из этого меняется, второе автоматически подхватывает изменения. Но, как видно из названия, инструмент служит лишь для одной частной задачи и не претендует ни на что большее (поиграть с отдельными грид-элементами в нем не получится). Может быть хорошей «затравкой» для начала самостоятельных экспериментов.
- Любая из универсальных песочниц типа CodePen, jsFiddle, dabblet и т.п. Кроме шуток: когда уже знаешь основы, зачастую бывает проще набросать нужный пример с нуля. Можно брать за основу любой готовый пример из интернета, в т.ч. из этой статьи. А с грид-инспектором из Firefox это еще проще (кстати, на mozilla.com есть прекрасная страница с полезными примерами гридов, наглядной инструкцией к инспектору и кучей полезных ссылок).
- Ну и как не упомянуть гриды на грядках — чудесный вводный курс в Grid Layout в форме забавной игры (нужно «поливать морковки» и «опрыскивать сорняки», управляя соотв. областями с помощью CSS-свойств) тех же авторов, кто раньше выпустили не менее увлекательную «обучалку» по флексбоксам на лягушатах.
P.S. Это тоже может быть интересно: