Как изменить высоту grid ячейки

Высота и ширина строк и столбцов в Grid Layout в CSS3, фиксированные, автоматические и пропорциональные размеры

Размеры строк и столбцов

Последнее обновление: 09.05.2017

Фиксированные размеры

В примерах, которые были рассмотрены в предыдущих статьях, ширина столбцов и длина строк устанавливались на основании фиксированных значений, которые
передаются свойствам grid-template-columns и grid-template-rows. Для определения размеров мы можем использовать самые различные единицы
измерения, которые нам доступны в CSS (px, em, rem, pt, %), например:

.grid-container {
	border: solid 2px #000;
	display: grid;
	grid-template-columns: repeat(3, 200px);
	grid-template-rows: repeat(3, 4.5em);
}

Автоматические размеры

Кроме точных размеров можно задавать автоматические размеры с помощью слова auto. В этом случае ширина столбцов и высота строк вычисляются
исходя из размеров содержимого:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
		<meta name="viewport" content="width=device-width" />
        <title>Grid Layout в CSS3</title>
		<style>
			.grid-container {
				border: solid 2px #000;
				display: grid;
				grid-template-columns: 8em auto auto;
				grid-template-rows: auto 4.5em auto;
			}
			.grid-item {
				text-align:center;
                font-size: 1.1em;
                padding: 1.5em;
                color: white;
			}
			.color1 {background-color: #675BA7;}
            .color2 {background-color: #9BC850;}
            .color3 {background-color: #A62E5C;}
            .color4 {background-color: #2A9FBC;}
			.color5 {background-color: #4e342e;}
		</style>
    </head>
    <body>
		<div class="grid-container">
			<div class="grid-item color1">Grid Item 1</div>
			<div class="grid-item color2">Grid Item 2</div>
            <div class="grid-item color3">Grid Item 3</div>
            <div class="grid-item color4">Grid Item 4</div>
            <div class="grid-item color5">Grid Item 5</div>
			<div class="grid-item color1">Grid Item 6</div>
            <div class="grid-item color2">Grid Item 7</div>
		</div>
	</body>
</html>

Здесь задано три строки и ти столбца. Первый столбец имеет фиксированную ширину в 8em, а второй и третий столбцы — автоматическую ширину.
И также первая и третья строки имеют автоматическую высоту, а вторая строка — фиксированную.

Автоматические размеры в Grid Layout в CSS 3

Пропорциональные размеры

Для установки пропорциональных размеров применяется специальная единица измерения fr.
Она представляет собой часть пространства (fraction), которое отводится для данного столбца или строки. Значение fr еще называют flex-фактором (flex factor).

Вычисление пропорциональных размеров производится по формуле:

flex-фактор * доступное_пространство  / сумма всех flex-факторов

При этом под доступным пространством понимается все пространство grid-контейнера за исключением фиксированных значений строк и столбцов.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
		<meta name="viewport" content="width=device-width" />
        <title>Grid Layout в CSS3</title>
		<style>
			*{
				box-sizing: border-box;
			}
			html, body{
				margin:0;
				padding:0;
			}
			.grid-container {
				height: 100vh;
				border: solid 2px #000;
				display: grid;
				grid-template-columns: 8em 2fr 1fr;
				grid-template-rows: 1fr 4.5em 1fr;
			}
			.grid-item {
				text-align:center;
                font-size: 1.1em;
                padding: 1.5em;
                color: white;
			}
			.color1 {background-color: #675BA7;}
            .color2 {background-color: #9BC850;}
            .color3 {background-color: #A62E5C;}
            .color4 {background-color: #2A9FBC;}
			.color5 {background-color: #4e342e;}
		</style>
    </head>
    <body>
		<div class="grid-container">
			<div class="grid-item color1">Grid Item 1</div>
			<div class="grid-item color2">Grid Item 2</div>
            <div class="grid-item color3">Grid Item 3</div>
            <div class="grid-item color4">Grid Item 4</div>
            <div class="grid-item color5">Grid Item 5</div>
			<div class="grid-item color1">Grid Item 6</div>
            <div class="grid-item color2">Grid Item 7</div>
		</div>
	</body>
</html>

flex factor и fr в Grid Layout и CSS 3

В данном случае имеются три столбца с шириной 2fr, 8em, 1fr. Поэтому ширина второго столбца будет вычисляться по формуле:

2 * (ширина_грида - 8em) / (2 + 1)

Ширина третьего столбца будет вычисляться по формуле:

1 * (ширина_грида - 8em) / (2 + 1)

И если первый столбец фиксированный с шириной 8em, то ширина второго и третьего столбца будут зависеть от ширины контейнера и будут автоматически масштабироваться при ее изменении.

В отношении строк все аналогично.

Грид-раскладка (CSS Grid Layout) представляет собой двумерную систему сеток в CSS. Гриды подойдут и для верстки основных областей страницы, и небольших элементов пользовательского интерфейса. Эта статья даёт общее представление о грид-раскладке и новой терминологии, которая является частью спецификации CSS Grid Layout Level 1. Более подробно показанные возможности будут описаны описаны далее в руководстве.

Что такое грид?

Грид представляет собой пересекающийся набор горизонтальных и вертикальных линий, образующих колонки и строки. Элементы могут быть помещены в грид в пределах линий этих колонок и строк. Грид имеет следующие особенности:

Фиксированные и гибкие размеры полос

Вы можете создать грид с фиксированными размерами полоc, например используя пиксели. Это установит грид на определенный пиксель, соответствующим желаемому макету. Вы также можете создать грид с гибкими размерами, используя проценты или новую единицу измерения — «fr», разработанную для этой цели.

Расположение элемента

Вы можете размещать элементы в заданном месте на гриде используя номера строк, имена или путём привязки к области грида. Грид также содержит алгоритм управления размещением элементов, не имеющих явной позиции на гриде.

Создание дополнительных полос для хранения контента

Вы можете определить явную сетку с помощью грид-раскладки. Cпецификация грид-раскладки достаточно гибкая, чтобы добавить при необходимости дополнительные строки и колонки. Также в нее включены такие возможности как, например, добавление «стольких колонок, сколько будет помещено в контейнер».

Управление выравниванием

Грид содержит механизм выравнивания, таким образом мы можем контролировать, как элементы выравниваются после размещения в области сетки и как выравнивается вся сетка.

Управление перекрывающимся контентом

В ячейку или область грида может быть помещено несколько элементов; эти элементы могут частично перекрывать друг друга. Такое наложение можно контролировать с помощью свойства z-index.

Грид – это мощная спецификация, и в сочетании с другими частями CSS, такими как flexbox, поможет вам создать макеты, которые ранее невозможно было построить в CSS. Все начинается с создания сетки в вашем грид-контейнере.

Грид-контейнер

Мы создаём grid контейнер, объявляя на элементе display: grid или display: inline-grid. Как только мы это сделаем, все прямые потомки этого элемента станут элементами сетки.

В этом примере у меня есть контейнер div с классом-обёрткой и пятью дочерними элементами внутри.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>

Я сделал .wrapper грид-контейнером.

.wrapper {
  display: grid;
}
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Все прямые потомки теперь являются грид-элементами. В браузере вы не увидите разницы с тем, как элементы отображались до помещения их в грид, поскольку грид сделан как одноколоночная сетка. На этой стадии вам, возможно, будет удобнее работать с инструментом «Грид-инспектор» (en-US), который является частью «Инструментов веб-разработчика» Firefox (Firefox’s Developer Tools). Если вы просмотрите этот пример в Firefox и проинспектируете грид, вы увидите маленький значок рядом с значением grid. Нажмите на него и сетка на этом элементе будет наложена в окне браузера.

Использование инструмента подсвечивания грида в инструментах веб-разработчика для просмотра грида

По мере вашего обучения и последующей работы с грид-раскладкой этот инструмент даст вам лучшее визуальное представление о том, что происходит с вашим гридом.

Если мы хотим, чтобы пример стал более похожим на сетку, нам нужно добавить полосы-колонки.

Грид-треки (грид-полосы)

Мы определяем ряды и колонки в нашей сетке при помощи свойств grid-template-columns и grid-template-rows. Это определения грид-треков (грид-полос). Грид-трек – это промежуток между любыми двумя линиями грида. На изображении ниже вы можете увидеть подсвеченный трек – это первый трек-строка в нашем гриде.

Контейнер с 3 грид элементами. Над ними светло зеленая область, которая является грид-треком.

Базовый пример

Я могу дополнить пример выше, добавив свойство grid-template-columns и задав размеры треков-колонок.

Сейчас я создал грид с тремя колонками шириной по 200px. Каждый дочерний элемент будет располагаться в отдельной ячейке грида.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: 200px 200px 200px;
}
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Единица измерения «fr»

Размер треков может быть задан с помощью любой единицы длины. Спецификация также вводит дополнительную единицу длины, позволяющую создавать гибкие (flexible) грид-треки. Новая единица длины «fr» представляет собой долю (fraction) доступного пространства в грид-контейнере. Следующее определение грида создаст три одинаковых по ширине трека, расширяющихся и сужающихся в соответствии с доступным пространством.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Разные размеры

В следующем примере мы создаём грид с треком в 2fr и двумя треками по 1fr. Доступное пространство разбивается на четыре части. Две части занимает первый трек, и две части – два оставшихся.

<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
}
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Смешение гибких и фиксированных размеров

В последнем примере смешаем треки с абсолютными размерами и треки с размерами, определенными в fr. Первый трек – 500 пикселей, фиксированная ширина убирается из доступного пространства. Оставшееся пространство разбивается на три части и пропорционально разделяется между двумя гибкими треками.

<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: 500px 1fr 2fr;
}
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Задание треков с помощью нотации repeat()

В огромных гридах с большим количеством треков можно использовать нотацию repeat(), чтобы повторить всю структуру треков или её часть. Например, определение грида:

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

Может быть также записано как:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

Repeat-нотация может быть использована для части структуры треков. В следующем примере я создал грид с начальным треком в 20 пикселей, затем повторил секцию с шестью треками по 1fr и завершил 20-пиксельным треком.

.wrapper {
  display: grid;
  grid-template-columns: 20px repeat(6, 1fr) 20px;
}

Repeat-нотация принимает список треков и использует его для создания повторяющегося шаблона треков. В следующем примере мой грид состоит из 10 треков: за треком в 1fr следует трек в 2fr. Этот шаблон будет повторен пять раз.

.wrapper {
  display: grid;
  grid-template-columns: repeat(5, 1fr 2fr);
}

Явный и неявный грид

При создании грида в примере выше мы специально объявляли треки-колонки при помощи свойства grid-template-columns, но грид также самостоятельно создавал строки. Эти строки — часть «неявного» грида. В отличие от него, «явный» грид состоит из строк и колонок, заданных с помощью grid-template-columns или grid-template-rows.

Если вы размещаете что-нибудь вне рамок определённого грида или из-за количества контента требуется большее количество грид-треков, грид создаёт строки и колонки в виде неявного грида. Размер этих треков по умолчанию задаётся автоматически в зависимости от находящегося в них контента.

Вы также можете задать размер треков, создаваемых в виде неявного грида, с помощью свойств grid-auto-rows (en-US) и grid-auto-columns (en-US).

В примере ниже мы используем grid-auto-rows, чтобы убедиться, что треки, создаваемые в неявном гриде, были высотой 200 пикселей.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 200px;
}
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Масштабирование треков и minmax()

При задании размеров явного грида или при определении размеров автоматически создаваемых колонок или строк нам может понадобиться задать трекам минимальный размер, но при этом быть уверенными, что они треки растянутся, чтобы вместить весь добавленный в них контент. Например, мне нужно, чтобы строки никогда не становились меньше 100 пикселей, но если контент занимает 300 пикселей в высоту, я бы хотел растянуть строку на эту высоту.

В гриде есть решение этой задачи – функция minmax(). В следующем примере я использую minmax() в качестве grid-auto-rows (en-US). То есть автоматически создаваемые строки будут как минимум 100 пикселей в высоту, а как максимум – примут значение auto. Использование auto означает следующее: высота строки «растягивается» до размера ячейки с самым высоким элементом контента.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: minmax(100px, auto);
}
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}
<div class="wrapper">
   <div>One</div>
   <div>Two
   <p>I have some more content in.</p>
   <p>This makes me taller than 100 pixels.</p>
</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>

Грид-линии

Нужно заметить, что когда мы определяем грид, мы определяем грид-треки, а не грид-линии. После этого грид обеспечивает нас пронумерованными линиями, для использования при размещении элементов. В нашем гриде с тремя колонками и двумя рядами у нас есть четыре линии колонок.

Диаграма, показывающая номера грид-линий.

Линии пронумерованы в соответствии с режимом написания (writing mode) документа. В языках с написанием слева направо, линия 1 – самая левая линия в гриде. В языках с написанием справа налево линия 1 – самая правая линия в гриде. Линии также могут быть именованы, и мы рассмотрим, как это сделать, в одном из последующих руководств этой серии.

Размещение элементов по линиям

Детально размещение элементов с помощью линий мы рассмотрим в дальнейшем. Следующий пример демонстрирует простой способ. При размещении элемента мы задаем линию, а не на трек.

В следующем примере я разместил первые два элемента на нашем трёхколоночном гриде с помощью свойств grid-column-start (en-US), grid-column-end (en-US), grid-row-start и grid-row-end (en-US). Работая слева направо, первый элемент размещен начиная с колоночной линии 1 и занимает пространство до колоночной линии 4, которая в нашем случае – самая правая линия грида. Наш элемент начинается со строчной линии 1 и заканчивается на строчной линии 3, таким образом занимая два строчных трека.

Второй элемент начинается с колоночной линии 1 и занимает один трек. Это поведение по умолчанию, поэтому нет необходимости задавать конечную линию. Элемент также занимает два строчных трека – со строчной линии 3 до строчной линии 5. Остальные элементы самостоятельно размещаются в свободном месте на гриде.

<div class="wrapper">
   <div class="box1">One</div>
   <div class="box2">Two</div>
   <div class="box3">Three</div>
   <div class="box4">Four</div>
   <div class="box5">Five</div>
</div>
.wrapper {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 100px;
}
.box1 {
    grid-column-start: 1;
    grid-column-end: 4;
    grid-row-start: 1;
    grid-row-end: 3;
}
.box2 {
    grid-column-start: 1;
    grid-row-start: 3;
    grid-row-end: 5;
}
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Примечание: Примечание. Не забывайте, что вы можете использовать Grid Inspector (en-US) в Firefox Developer Tools, чтобы посмотреть, как элементы размещаются по линиям грида.

Сокращения при использовании размещения по линиям

Обычные значения, использованные выше, могут быть умещены в одну строку: для колонок – с использованием grid-column (en-US), для строк – с использованием grid-row (en-US). Следующий пример сделает такое же расположение, как и предыдущий, но с менее громоздким кодом CSS. значение до слэша («/») – это первая линия, значение после – последняя линия.

Можно опустить конечное значение, если область занимает только один трек.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 100px;
}
.box1 {
  grid-column: 1 / 4;
  grid-row: 1 / 3;
}
.box2 {
  grid-column: 1;
  grid-row: 3 / 5;
}

Грид-ячейки

Грид-ячейка – наименьшая часть на гриде. Концептуально она похожа на ячейку таблицы. Как мы видели в предыдущих примерах, едва грид определён для родительского элемента, дочерние элементы автоматически размещаются в каждой ячейке заданного грида. На рисунке ниже я выделил первую ячейку грида.

Выделена первая ячейка грида

Грид-области

Элементы могут занимать одну или несколько ячеек внутри строки или колонки, таким образом, создаётся грид-область. Грид-области должны быть перпендикулярными – невозможно создать область, например, в форме буквы «L». Выделенная грид-область на рисунке ниже занимает два строчных трека и два колоночных.

Грид-область

Промежутки

Промежутки (gutters), или дорожки (alleys), между грид-ячейками могут быть созданы с помощью свойств grid-column-gap (en-US) и grid-row-gap (en-US), или с помощью сокращённого свойства grid-gap (en-US). В примере ниже я создаю 10-пиксельный промежуток между колонками и промежуток в 1em между строками.

.wrapper {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-column-gap: 10px;
   grid-row-gap: 1em;
}

Примечание: Примечание. Когда грид был добавлен в браузеры, у свойств column-gap, row-gap и gap был префикс «grid-»: «grid-column-gap», «grid-row-gap» «grid-gap» соответственно.Сейчас все браузеры поддерживают значения без префикса, однако версии с префиксом будут поддерживаться как псевдонимы, что делает их использование безопасным.

<div class="wrapper">
   <div>One</div>
   <div>Two</div>
   <div>Three</div>
   <div>Four</div>
   <div>Five</div>
</div>
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Пространство, занимаемое промежутками, будет учитываться как пространство, расположенное перед гибкими треками, заданными с помощью fr, и приписанное к длине этих треков, и промежутки служат для задания размеров как обычные грид-треки, однако в промежутках нельзя ничего размещать. С точки зрения размещения по линиям, промежутки действуют в роли толстой линии.

Вкладывание гридов

Грид-элемент может быть и грид-контейнером. В следующем примере у меня есть созданный ранее трёхколоночный грид, с двумя нашими размещенными элементами. В данном случае у первого элемента есть несколько подэлементов. Поскольку эти подэлементы не являются прямыми потомками грида, они не участвуют в структуре грида и отображаются в нормальном потоке документа.

Вложенные гриды в потоке

Вкладывание без подгридов

Если я задам для box1 значение display: grid, я могу установить для него структуру треков, и он тоже станет гридом. Элементы будут размещены на этом новом гриде.

.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
   display: grid;
   grid-template-columns: repeat(3, 1fr);
}
<div class="wrapper">
   <div class="box box1">
       <div class="nested">a</div>
       <div class="nested">b</div>
       <div class="nested">c</div>
    </div>
    <div class="box box2">Two</div>
    <div class="box box3">Three</div>
    <div class="box box4">Four</div>
    <div class="box box5">Five</div>
</div>
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
}
.box {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.box1 {
  grid-column: 1 / 4;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

В данном случае вложенный грид не связан с родительским. Как вы можете видеть, он не наследует значение свойства gap родителя и линии вложенного грида не выравниваются по линиям родительского грида.

Подгрид (Subgrid)

В рабочих черновиках спецификации гридов второго уровня есть функциональность, называемая подгридом, которая позволит нам создавать вложенные гриды, использующие структуру треков родительского грида.

Примечание: Примечание. Эта функция поддерживается в браузере Firefox 71, который в настоящее время является единственным браузером, обеспечивающим выполнение подгрида.

Согласно этой спецификации, мы можем отредактировать приведенный выше пример вложенного грида, изменив grid-template-columns: repeat(3, 1fr) на grid-template-columns: subgrid. Вложенный грид будет использовать родительскую структуру треков для размещения элементов.

.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
   display: grid;
   grid-template-columns: subgrid;
}

Размещение элементов с помощью z-index

Несколько грид-элементов могут занимать одну и ту же ячейку и поэтому мы можем использовать свойство z-index, чтобы контролировать порядок наложения перекрывающихся элементов.

Наложение без z-index

Если мы вернемся к нашему примеру с элементами, размещёнными по номерам линий, мы можем изменить его, чтобы два элемента перекрывались:

<div class="wrapper">
   <div class="box box1">One</div>
   <div class="box box2">Two</div>
   <div class="box box3">Three</div>
   <div class="box box4">Four</div>
   <div class="box box5">Five</div>
</div>
.wrapper {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-auto-rows: 100px;
}
.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
}
.box2 {
   grid-column-start: 1;
   grid-row-start: 2;
   grid-row-end: 4;
}
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.box {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Элемент box2 теперь перекрывает box1, он отображается сверху, поскольку в исходном коде находится ниже.

Управление порядком отображения

Мы можем управлять порядком наложения элементов с помощью свойства z-index – точно так же, как позиционированными элементами. Если мы зададим для box2 значение z-index, меньшее, чем у box1, он отобразится под элементом box1.

.wrapper {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   grid-auto-rows: 100px;
}
.box1 {
   grid-column-start: 1;
   grid-column-end: 4;
   grid-row-start: 1;
   grid-row-end: 3;
   z-index: 2;
}
.box2 {
   grid-column-start: 1;
   grid-row-start: 2;
   grid-row-end: 4;
   z-index: 1;
}
<div class="wrapper">
    <div class="box box1">One</div>
    <div class="box box2">Two</div>
   <div class="box box3">Three</div>
   <div class="box box4">Four</div>
   <div class="box box5">Five</div>
</div>
* {box-sizing: border-box;}
.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}
.box {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.nested {
    border: 2px solid #ffec99;
    border-radius: 5px;
    background-color: #fff9db;
    padding: 1em;
}

Что дальше?

В данной статье мы очень кратко рассмотрели спецификацию Grid Layout. Поиграйте с примерами кода и переходите к следующей части нашего руководства, где мы начнём углубляться в детали CSS Grid Layout.

У нас идёт цикл статей о современном CSS: как на нём собирать штуки, о которых раньше мы могли только мечтать. В прошлый раз мы говорили о CSS-сетке Grid. Сегодня мы её будем настраивать.

Коротко главное из первой части:

  • В CSS есть много способов расставить объекты на странице: по абсолютным координатам, относительно друг друга, закрепив в каком-то месте страницы и т. д. 
  • Один из полезных для веб-разработчика способов — разделить страницу на столбцы и строки, как будто это таблица или сетка. И внутри этой сетки расставить объекты.
  • Инструмент Grid как раз помогает нарисовать на странице воображаемую сетку и выравнивать объекты по ней.
  • Grid достаточно гибкий, чтобы учесть меняющуюся ширину экрана и предсказуемо управлять столбцами и строками.

Сегодня поработаем с размером ячеек сетки, чтобы в следующий раз собрать из них что-то действительно полезное. 

Готовим шаблон

Начнём с пустого шаблона. Чтобы было наглядно видно, как в сетке располагаются ячейки, сделаем так:

  1. Создадим общий класс, который будет отвечать за сетку целиком. Пока не будем делать разбивку на строки и столбцы.
  2. В нём сделаем видимые внешние границы — так мы поймём, какого размера сетка у нас получается.
  3. Каждую ячейку закрасим светло-оранжевым цветом, чтобы видеть, где заканчивается одна ячейка и начинается другая.
  4. Добавим в оформление ячеек отступы и скругления для красоты.
  5. После этого в теле страницы создадим новый блок и применим к нему наш стиль с сеткой.
  6. Добавим 10 новых элементов в сетку и посмотрим, что получится.
<!DOCTYPE html>
<html>

<head>
  <title>Grid</title>
  <style>

    body{
      /*настраиваем шрифт*/
      font-family: Arial, Helvetica, sans-serif;
    }

    /*общие настройки сетки*/
    .grid {
      /*рисуем зелёные рамки*/
      border: 5px solid #d1e231;
      /*подключаем сетку*/
      display: grid;
    } 

    /*внешний вид ячеек*/
    .grid > * {
      /*фоновый цвет*/
      background-color: #ffbf94;
      /*скругление углов*/
      border-radius: 5px;
      /*отступ от содержимого до края ячейки*/
      padding: 7px;
      /*расстояние от одной границы ячейки до другой*/
      margin: 1px;
    }

  </style>
</head>

<body>
  <!-- создаём контейнер, который будет отвечать за нашу сетку -->
  <div class="grid">
    <!-- и создаём 10 вложенных элементов -->
    <div>Элемент 1</div>
    <div>Элемент 2</div>
    <div>Элемент 3</div>
    <div>Элемент 4</div>
    <div>Элемент 5</div>
    <div>Элемент 6</div>
    <div>Элемент 7</div>
    <div>Элемент 8</div>
    <div>Элемент 9</div>
    <div>Элемент 10</div>
  </div>
</body>
</html>

Вот что у нас получается, если у сетки не задавать никаких параметров:

  • элементы располагаются друг под другом в одну колонку;
  • сетка растягивается по ширине на весь экран;
  • элементы тоже растягиваются по ширине;
  • по высоте сетка занимает ровно столько, чтобы вместить всё содержимое. На всю высоту сетка автоматически не растягивается.

Формируем строки и столбцы

Давайте посмотрим, как добавление строк и столбцов в сетку влияет на положение и размер ячеек. 

Сделаем в сетке три колонки по 150 пикселей:

grid-template-columns: 150px 150px 150px;

Сетка сразу уменьшилась по высоте, подстраиваясь под количество элементов. Теперь укажем нужную высоту для элементов:

grid-template-rows: 50px;

Смотрите, высота поменялась только у первой строки. Остальные остались той же высоты, что и раньше, потому что мы указали только один параметр в команде grid-template-rows. Сделаем 5 строк одинаковой высоты:

grid-template-rows: 50px 50px 50px 50px 50px ;

Так как мы явно указали, что нам в сетке нужно 5 строк, то у нас появилась пустая пятая строка. В ней пока никаких элементов, но сетка уже предусмотрела для них свободное место.

Чтобы не писать пять раз подряд размер 50px, можно использовать такую команду:

grid-template-rows: repeat(5, 50px);

Она повторяет нужный нам размер (50 пикселей) определённое количество раз — в нашем случае это 5 раз. То же самое работает и с колонками — сделаем 4 одинаковые колонки используя функцию repeat():

grid-template-columns: repeat(4, 150px);

Адаптивные размеры и автозаполнение

Теперь сделаем так:

  • поставим три строки вместо пяти;
  • последнюю строку растянем вниз до конца окна — используем для этого 1fr;
  • столбцы сделаем одинаковой ширины.

Запишем это в разделе со стилями:

grid-template-rows: 50px 1fr 50px;
grid-template-columns: repeat(4, 1fr);

Кажется, что 1fr, который должен был растянуть вторую строку на всё свободное место, не работает. Но с ним всё в порядке, ошибки тут нет, смотрите, что произошло на самом деле:

  1. Первая строка получила ширину 50 пикселей.
  2. Третья строка тоже получила 50 пикселей.
  3. После этого браузер, глядя на 1fr, стал высчитывать, какую высоту сделать у второй строки.
  4. Браузер знает, что 1fr должен заполнить всё оставшееся свободное место в сетке, но у нас нижняя граница сетки прилегает вплотную к последней строке.
  5. Это значит, что свободного места в сетке нет, поэтому браузер учёл все внутренние отступы из общих настроек ячейки и сделал вторую строку минимальной высоты.

Чтобы это исправить, нам нужно явно задать общую высоту сетки — например в пикселях:

height: 300px;

Чтобы сетка растянулась по высоте на всё окно, используют относительные единицы, например, vh — она указывает, сколько процентов от высоты окна будет занимать элемент. Чтобы растянуть сетку до края, напишем:

height: 100vh;

Полосы прокрутки появились из-за того, что общий размер сетки у нас больше 100% высоты окна — к высоте добавились внешние и внутренние отступы сетки.

Если нам нужно сделать столбцы и строки в определённых пропорциях, также используем fr — он подгонит всё под размер окна:

height: 92vh;
grid-template-columns: 1fr 2fr 2fr 1fr ;
grid-template-rows: 50px 1fr 50px;

Теперь у нас получился красивый шаблон на 12 ячеек:

  • верхняя и нижние строки высотой по 50 пикселей;
  • средняя растягивается на всю высоту;
  • вторая и третья колонки в два раза шире, чем боковые.

Используя нужные размеры, автозаполнение и полезные функции из нашей подборки современных CSS-команд, можно получить любой шаблон для вёрстки страницы.

Что дальше

Статья получилась большой, поэтому про работу с ячейками и областями сетки поговорим в другой раз. А потом сверстаем на сетке полноценную страницу-портфолио.

Мы давно изучали CSS-гриды, сами и вместе с зарубежными авторами. Тогда же возникла мысль оформить результат в виде подробного руководства по ним, вроде этого по флексбоксам. Это оказалось не так-то просто: стандарт большой, вводит множество новых понятий, к тому же эти понятия переплетены друг с другом, совсем как полосы самих гридов (как показать грид-области без привязанных к ним грид-элементов, и наоборот?). Поэтому работа над статьей, скажем прямо, несколько затянулась:) Но теперь, когда грид-раскладка уже поддерживается почти повсеместно (Firefox 52+, Chrome 57+, Opera 44+, Safari 10.1+/iOS 10.3+ Safari, Яндекс-Браузер 17+, а также в Android WebView), мы рады представить вам результат трудов. Надеемся, он поможет разобраться в горах новых возможностей. Это не «полное руководство» (полностью описать все возможности CSS Grid в одной статье просто нереально!), но мы постарались упомянуть некоторые важные моменты, упущенные многими из «полных руководств». Любые дополнения и уточнения приветствуются!

Краткое содержание:

  1. Основа и терминология
  2. Грид-контейнер и его свойства
    • Создание грид-контейнера
    • Разметка колонок и рядов
      • Размеры грид-полос
      • Имена грид-линий
      • Функция repeat()
    • Разметка грид-областей
    • Сокращенная запись для колонок, рядов и областей
    • Неявный грид (автоматические ряды и колонки)
    • Алгоритм авторазмещения элементов в контейнере
    • Одно свойство, чтоб править всеми: grid
    • Промежутки между ячейками (грид-интервалы)
    • Выравнивание и центрирование грид-полос в грид-контейнере
  3. Грид-элементы и их свойства
    • Привязка грид-элемента к грид-линиям
      • По номеру
      • По имени
      • По имени и номеру
      • Сокращенные свойства
    • Размещение грид-элемента в грид-области
    • Автоматическое размещение грид-элементов
    • Порядок грид-элементов
    • Выравнивание и центрирование грид-элемента в грид-области
    • Наложение грид-элементов
  4. Песочницы

Основа и терминология

Грид — это двумерная (в отличие от от одномерных флексбоксов) сетка. Как табличная, только виртуальная, не связанная с разметкой. Состоит из следующих элементов:

  • Грид-контейнер — элемент, в котором строится сетка.
  • Грид-элементы — элементы, размещаемые по сетке. Важно: они должны быть непосредственными потомками грид-контейнера (как и во флексбоксах флекс-элементы должны быть непосредственными потомками флекс-контейнера).
  • Грид-линии — невидимые вертикальные и горизонтальные линии, разделяющие грид на ячейки и формирующие его структуру. Грид-линии автоматически нумеруются, а также им можно задавать имена. К грид-линиям можно привязывать грид-элементы — и по номерам, и по именам, как удобнее.
  • Грид-полосы — то, что ограничено парой соседних грид-линий. Вертикальные грид-полосы — это колонки грида (аналог столбцов таблицы), горизонтальные — ряды (аналог строк).
  • Грид-ячейки — то, что получается на пересечении двух грид-полос (колонки и ряда). Аналог ячейки таблицы.
  • Грид-области — прямоугольники из M×N смежных грид-ячеек (1×1 и больше). Каждая грид-область ограничена двумя парами грид-линий (парой вертикальных и парой горизонтальных). В них и размещаются грид-элементы. Грид-областям тоже можно задавать имена.
  • Грид-интервалы — пустые пространства (отступы) между соседними грид-полосами. Аналог border-spacing в таблице.

See the Pen LypJVK by Ilya Streltsyn (@SelenIT) on CodePen.

Ограничение, что грид-элементы должны быть непосредственными потомками грид-контейнера, в будущем снимут подсетки (subgrids). Пока их нет, его можно частично обойти с помощью display:contents или эмулировать CSS-переменными.

Визуализировать грид-линии умеет отладчик Firefox (иконка в виде решетки, указанная стрелкой):

скриншот отладчика 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 — то же самое, но после размещения грид-элементов оставшиеся пустыми грид-полосы сжимаются до нуля, а интервалы между ними объединяются в один интервал. Т.е. пустые полосы как будто выбрасываются. Если полос вмещается пять, но элемента только три — в итоге и полос будет только три.

Есть несколько важных ограничений:

  1. Нельзя вкладывать repeat в другой repeat.
  2. С 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) — нельзя
  3. repeat c auto-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) — нельзя (2 repeat с неизвестным количеством повторений)
  4. Если есть repeat c auto-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, paddingborder-* и большинства прочих свойств с 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. Это тоже может быть интересно:

CSS Grid Layout — это новое многообещающее явление в мире верстки. Используя Grid, можно построить макеты, которые ранее невозможно было построить в CSS. С ним возможности чуть ли не безграничны. Grid претендует на звание «лучшей системы для вёрстки макетов HTML». В этой статье я попробую разобраться какой он, этот Grid, на вкус и доступно поделиться знаниями с вами.

Grid поддерживается почти всеми браузерами, поэтому изучать уже пора!

Базовые знания

Grid — это сетка с элементами на ней. Расставлять элементы можно как угодно. Представьте себе шахматную доску и фигуры, Grid контейнер это доска, элементы это фигуры. А дальше ставь как нравится.

Grid — это набор горизонтальных и вертикальных «линий», которые пересекаются между собой и создают сетку из рядов и колонок. Элементы могут быть помещены в сетку, опираясь на номер линии или номер ряда/колонки.

Чтобы разобраться с Грид-сеткой нужно понять из чего конкретно состоит эта сетка. Для этого хорошенько изучите схему ниже и описание к ней.

Схема Grid сетки.
Описание Грид сетки
  • Контейнер — содержит Grid сетку, в которой находятся элементы.

  • Элементы — HTML элементы внутри сетки. Ими станут HTML элементы первого уровня (прямые дети контейнера). Чтобы элемент появился в сетке, в нем (внутри) элемента должно быть хоть что-то (текст, другие HTML теги). Пустой элемент — это всего лишь ячейка для расположения в нем чего-либо.

  • Линии — это образные линии (на самом деле никаких линий нет), разделяющие сетку на колонки и ряды, они создают структуру сетки. Линии автоматически нумеруются. Также линиям можно указывать имена, чтобы потом прикреплять к ним элементы по номеру или по имени линии. По сути линия — это номер или имя колонки/ряда. Расстояние между линиями (колонками/рядами) можно указать через grid-gap:, grid-row-gap:, grid-column-gap:.

  • Ряд/колонка (row/column, track) — все что находится между соседними линиями, т.е. линии разделяют сетку на ряды и колонки.

  • Ячейка (cell) — место куда будет расположен элемент. Ячейка это пересечение колонки и ряда.

  • Область (area, поле) — объединение одной или нескольких ячеек в общую ячейку (поле). Это такая большая ячейка также ограниченная линиями. Области можно задать имя, чтобы удобно было помещать туда элементы.

  • Разрыв (gap) — расстояние между рядами и колонками. Разрывает линию на две. Так между линиями, а как следствие и колонками/рядами, ячейками появляется пустое место. Это своего рода margin, border-spacing между ячейками. По умолчанию линия между ячейками всего одна (ячейки слеплены), но если указать разрыв, то мы разорвем линию, и появится расстояние между колонками/рядами, при этом номер или имя линии (колонки/ряда) остается одно.

Для включения Grid, любому HTML элементу достаточно присвоить css свойство display:grid; или display:inline-grid;.

.grid { display: grid; }
.inline-grid { display: inline-grid; }
<div class="grid">
	<div>display: grid</div>
</div>

Текст, в котором есть
<div class="inline-grid">
	<div>display: inline-grid</div>
</div>
продолжение текста

После включения grid свойства, внутри контейнера создаются grid сетка, а все вложенные элементы (первого уровня) станут ячейками сетки.

.grid { display: grid; }
<div class="grid">
	<div>1</div>
	<div>2</div>
</div>

Пример создания грид-блока с двумя колками и тремя рядами разных размеров:

.grid{
	display: grid;
	grid: 1fr 25% 30px / 40% 1fr; /* ряды / колонки */
	grid-gap: 1em;
	height: 200px;
}
<div class="grid">
	<div class="item">item 1</div>
	<div class="item">item 2</div>
	<div class="item">item 3</div>
	<div class="item">item 4</div>
	<div class="item">item 5</div>
	<div class="item">item 6</div>
</div>

Особенности Grid

Элементы Grid сетки можно расставлять сразу на несколько полей сетки. Можно менять направление или расположения элементов в сетке. Колонкам и рядам можно давать имена. Можно создавать шаблон сетки и расставлять элементы по шаблону.

  • Размеры колонок/рядов. Сетку можно создавать с точными или гибкими размерами колонок/рядов (шириной/высотой). Точные это px, em, %, а гибкие новая единица измерения в grid fr (фракция — свободное место в сетке).

  • Расположение элемента. Элементы можно размещать в указанном месте сетки, указав номер колонки/ряда или их имя (если оно есть). Или путем привязки элемента к области Grid (область нужно создать). Если не указать конкретное расположение элемента в сетке, то элемент размещается по умолчанию в первую свободную ячейку: как во flex: по горизонтали (→) или по вертикали (↓). Поведение по умолчанию можно изменить через свойство grid-auto-flow:.

  • Выравнивание элементов. Элементы внутри ячейки можно выравнивать по горизонтали/вертикали. Выравнивается вложенный в ячейку элемент, а не сама ячейка. Например, в контейнере есть вложенный элемент первого уровня (это ячейка), внутри него есть «текст» или какой-то «div» (текст или div — это реальный элемент) выравнивание элемента выровняет вложенный в ячейку элемент внутри ячейки (размеры ячейки при этом не изменятся).

  • Несколько элементов в одной ячейке. В одной ячейке или области можно разместить несколько элементов. Чтобы указать кто «выше» (важнее) и кто «ниже» (неважный), нужно использовать css свойство z-index:.

  • Расширение сетки. Сколько колонок/рядов имеет сетка обычно указывается сразу, но если разместить элемент за пределами сетки (указать ему номер ряда/ячейки, который выходит за пределы сетки), тогда сетка автоматически расширяется и создаются дополнительные линии (колонки/ряды).

CSS свойства Grid

Для контейнера

display:

Включает grid свойство для элемента. Под это свойство попадает сам элемент и вложенные в него элементы: затрагиваются только потомки первого уровня — они станут элементами grid контейнера.

  • grid — элемент растягивается на всю ширину и имеет свое полное пространство среди окружающих блоков. Происходит перенос строк в начале и в конце блока.
  • inline-grid — элемент обтекается другими элементами. При этом его внутренняя часть форматируется как блочный элемент, а сам элемент — как встроенный.

grid и inline-grid отличаются тем что по-разному взаимодействуют с окружающими элементами, подобно display:block и display:inline-block.

grid-template-rows:
grid-template-columns:

Указывают из скольки рядов (строк) и скольки колонок состоит сетка и какие у них размеры. Т.е. указывается сразу два понятия: сколько и какой размер.

В значении через пробелы указываются размеры: высота ряда (rows) или ширина колонки (columns). Сколько раз будет указан размер, столько будет рядов/колонок.

// синтаксис:
grid-template-rows:    размер  размер  ...;
grid-template-columns: размер  размер  ...;

grid-template-rows:    [line-name] размер  [line-name] размер ... [last-name];
grid-template-columns: [line-name] размер  [line-name] размер ... [last-name];
  • размер — это высота ряда или ширина колонки, может быть:

    • auto — размер ряда/колонки подстраивается под размеры элементов, так, чтобы уместился самый большой из них. Не дает сжиматься меньше min-width или min-height самого широкого или высокого элемента соответственно. Не дает растягиваться больше, чем max-content. Если в контейнере есть свободное место, то размер может растянуться до конца контейнера.

    • px, em, %, vh, vw — размер абсолютный (px, pt), относительный (em, vw, vh) или в % от ширины/высоты контейнера.

    • fr (фракция — свободное место в сетке) — специальная единица измерения в grid. Свободное место в контейнере делится на фракции, так если одной колонке указать 1fr, а другой 2fr, то вторая будет больше первой в 2 раза и обе они заполнят все свободное пространство. Аналог flex-grow: у флексов. Тут можно также указывать дробные значения: 0.5fr, 2.3fr.

    • min-content — наименьший размер контента. Для текста это ширина самого длинного слова или неразрывного фрагмента.

    • max-content — наибольший размер контента. Для текста это длина самой большой строки без переносов.

    • fit-content( max ) — функция которой передается макс. размер. Если контент меньше этого размера, ведет себя как auto, если больше, то ограничивает размер ряда/колонки до указанного в параметре max.

    • minmax( min, max ) — функция, позволяет разом указать минимальный и максимальный размер.
  • line-name (имя линии) — перед размером можно указать (создать) имя для линии (ряда/колонки). Имя указывается в квадратных скобках [имя] 100px. Также можно указать сразу несколько имен через пробел внутри квадратных скобок: [имя еще_имя] 100px. Символы в имени можно использовать любые, в том числе кириллицу.

  • last-name (последнее имя) — указанное имя станет именем начальной линии ряда/колонки, но ряд/колонка состоит из двух линий (они ведь имеют размер). Так имя линии является именем начала одной колонки (ряда) и именем конца предыдущей колонки (ряда). И так вот заполняется сетка, но в конце остается ряд/колонка и указанное для неё имя это имя только начальной линии этого ряда/колонки, а у конечной линии имени нет. Такое имя последней линии можно указать в конце. Т.е. получается так: [имя] 100px [имя2] 100px [последнее-имя].

Примеры значений:

// grid-template-columns: может принимать все те же значения
grid-template-rows: none;

grid-template-rows: auto auto;
grid-template-rows: 100px 1fr;
grid-template-rows: [linename]  100px;
grid-template-rows: [linename1] 100px [linename2 linename3];
grid-template-rows: minmax(100px, 1fr);
grid-template-rows: fit-content(40%);
grid-template-rows: repeat(3, 200px);

grid-template-rows: 200px repeat(auto-fill, 100px) 300px;
grid-template-rows: minmax(100px, max-content)  repeat(auto-fill, 200px) 20%;
grid-template-rows: [linename1] 100px
					[linename2] repeat(auto-fit, [linename3 linename4] 300px)
					100px;
grid-template-rows: [linename1 linename2] 100px
					repeat(auto-fit, [linename1] 300px) [linename3];

// глобальные
grid-template-rows: inherit;
grid-template-rows: initial;
grid-template-rows: unset;

Примеры:

Создадим сетку (контейнер) с тремя колонками и тремя рядами последняя колонка и ряд будут иметь одинаковое имя ‘main’

.grid {
	grid-template-columns: 100px  10%  [main] 800px;
	grid-template-rows: 100px  10%  [main] 800px;
}

Если не указать имя, то ряд/колонка автоматом получает два порядковых числовых имени: положительное и отрицательное:

grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;

Укажем конкретные имена (обратите внимание как указывается имя для последней линии):

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:

grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];

Если в перечисление размеров колонок есть повторяющиеся части, то можно использовать функцию repeat():

grid-template-columns: repeat(3, 20px [col-start]) 5%;

// в результате получим:
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;

Если несколько строк имеют одно и то же имя, на них можно ссылаться по имени и порядковому числу:

.item {
	grid-column-start: col-start 2;
}

fr позволяет указать размер относительный оставшегося свободного места в контейнере. В этом примере свободное место в контейнере делится на число указанных фракций (у нас 3) и для каждой определяется ширина. Так если ширина контейнера 90px то каждая колонка будет шириной по 30px.

grid-template-columns: 1fr 1fr 1fr;

Свободное пространство высчитывается после того как посчитаны жесткие размеры (включая разрывы). В этом примере размер свободно пространства высчитывается как ширина контейнера минус 50px.

grid-template-columns: 1fr 50px 1fr 1fr;
grid-template-areas:

Позволяет создать визуальный шаблон сетки. В этом свойстве задаются имена ячейкам, а затем элементы привязываются к этим именам через свойство grid-area: указываемое для отдельного элемента.

Синтаксис шикарен, потому что визуально показывает как выглядит сетка:

grid-template-areas: "имя  имя2  имя3"
					 "имя  имя4  имя5"
					 "имя  none   .";

// или можно так
grid-template-areas: "имя  имя2 имя3"  "имя  имя4 имя5"  "имя6 none .";

// или одинарные кавычки
grid-template-areas: 'имя  имя2 имя3'  'имя  имя4 имя5'  'имя6 none .';
  • "имя имя2 имя3" — в значении внутри кавычек нужно через пробелы указывать имена. Каждые кавычки с именами будут представлять собой ряд сетки, а имена внутри кавычек задают имена ячейкам внутри этого ряда.

  • "имя имя имя2" — если указать одно и тоже имя несколько раз подряд, то имя объединит ячейки и мы получим область (большую ячейку). Объединять ячейки таким способом можно не только внутри ряда, но и между рядами.

  • . (точка) — указывается вместо имени и обозначает ячейку которую нужно пропустить (пустую ячейку). Можно использовать несколько точек подряд, пока между ними нет пробела они будут считаться за одну.

  • none — область не определена

Заметки:

  • Символы в имени можно использовать любые, в том числе кириллицу.
  • Каждый ряд должен иметь одинаковое количество ячеек.

  • При использовании этого метода линии (включая последнюю линию) получают имена автоматически. Например, если область называется bar, то имя начальной линии ряда и колонки у этой области будет bar-start, а имя последней bar-end. Это значит, что некоторые линии будут иметь много имен. Например крайняя левая линия из примера ниже (шаблон страницы) будет иметь сразу три имени: header-start, main-start и footer-start.

    Такая же логика работает и наоборот, если линиям указать имена дом-start и дом-end, то все что находится межу этими линиями превращается в область (ячейку) с именем дом.

grid-template-areas: также можно указывать в первом значении свойств:

  • grid-template: ‘имя имя2’;
  • grid: ‘имя имя2’;

Примеры:

Шаблон страницы. Создадим сетку с четырьмя колонками и тремя рядами. Весь верхний ряд будет шапкой (header), средний ряд будет контентом (main) и сайдбаром (sidebar), между которыми оставим место (.). И последний рад будет подвалом (footer).

.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";
}

Размеры и области можно указывать одновременно:

.grid {
	display: grid;

	grid-template-rows: [header-top] minmax( 6em, auto) [header-bottom  main-top] 1fr [main-bottom];
	grid-template-columns: 1fr 30%;
	grid-template-areas: "header  header"
						 "main    menu";
}

.header { grid-area: header; }
.main   { grid-area: main; }
.menu {
	/* прикрепление к области (ячейке) */
	grid-area: menu;

	/* такое же прикрепление, но к именам линий ряда */
	grid-row: main-top   / main-bottom;
	/* или */
	grid-row: menu-start / menu-end;
	/* или */
	grid-row: 2 / 3;
}
grid-template:

Позволяет разом указать три свойства: grid-template-rows, grid-template-columns и grid-template-areas.

// синтаксис:
grid-template: none;
grid-template: grid-template-rows / grid-template-columns;
grid-template: [ line-names? "строка" размер? line-names? ] ...
grid-template: [ line-names? "строка" размер? line-names? ] ... / [ line-names? размер ] ... line-names?

// то что в [] или до ? — можно не указывать
// ...  — можно повторять

Это свойство можно заменить на сокращенное grid: grid-template-rows / grid-template-columns

Примеры:

В первом параметре (в рядах) можно указать шаблон (области). 25px — это высота ряда.

grid-template: "header header header" 25px
			   "footer footer footer" 25px
			   / auto  50px   auto;

Также можно указывать имена для линий ряда:

grid-template: [header-top] "a   a   a"     [header-bottom]
				 [main-top] "b   b   b" 1fr [main-bottom]
						  / auto 1fr auto;

// в результате получится вот это:

grid-template-areas: "a a a"
					 "b b b";
grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom];
grid-template-columns: auto 1fr auto;

auto

auto

1fr

b

header-top / a-start

header-bottom / a-end / main-top / b-start

main-bottom / b-end

1fr

auto

a-start / b-start

a-end / b-end

a

a

a

b

b

grid-template: не сбрасывает свойства для рядов/колонок по умолчанию: grid-auto-columns:, grid-auto-rows:, grid-auto-flow:. Чтобы это сделать, лучше вместо grid-template: использовать свойство grid:.

repeat() — функция

Позволяет повторять что-либо N раз. Используется при создании колонок/рядов в свойствах: grid-template-rows:, grid-template-columns:, grid-template:.

repeat( сколько_раз, что_повторять )

Варианты использования repeat():

  1. Повторение любого числа рядов/колонок указанное число раз.

    repeat( 2, 50px )       // 50px 50px
    repeat( 2, 50px 70px )  // 50px 70px 50px 70px
  2. Повторение одного ряда/колонки до заполнения контейнера. Количество повторов при этом задается через:

    • auto-fill — повторяет ряд/колонку пока есть место в контейнере. Хотя бы одно повторение будет всегда.
      • если контейнер ограничен максимальным размером, ряд/колонка повторяется пока есть место вставить очередной ряд/колонку.
      • если у контейнера задан минимальный размер, ряд/колонка повторяется пока не превысят этот минимум.
    • auto-fit — то же самое, но после размещения элементов оставшиеся пустыми ряд/колонка сжимаются и исчезают, в результате контейнер всегда будет выглядеть заполненным (без пустых мест на краях) (это видно визуально только если в контейнере есть резиновый блок).

Ограничения по repeat():

  • Нельзя вкладывать repeat() в repeat().
  • С auto-fill и auto-fit можно повторять только не резиновые размеры (имеющие конечную ширину/высоту). Т.е. нет смысла использовать min-content, max-content, fr, auto — все они резиновые и в результате мы получим только один ряд/колонку без каких-либо повторений.

    repeat( auto-fill, 100px )             // можно
    repeat( auto-fit, minmax(100px, 1fr) ) // можно
    repeat( auto-fill, auto )              // нельзя
    repeat( auto-fit, 1fr )                // нельзя
  • repeat() c auto-fill или auto-fit может быть только один на одно свойство (grid-template-rows: или grid-template-columns:).

    // можно
    grid-template-columns: repeat(3, 50px 5%) repeat(auto-fill, 100px) repeat(4, 80px)
    // нельзя (2 repeat с неизвестным количеством повторений)
    grid-template-columns: repeat(auto-fill, 50px) repeat(2, 100px) repeat(auto-fit, 80px)
  • Если есть repeat() c auto-fill или auto-fit, то в остальных repeat для этого же свойства нельзя повторять неточные размеры: *-content, fr или auto.
    // можно (в первом repeat повторяется конкретная ширина в процентах)
    grid-template-columns: repeat(4, 10%) repeat(auto-fill, 10em)
    // нельзя (в одном repeat есть auto-fill, а в другом repeat повторяется заранее неизвестная ширина).
    grid-template-columns: repeat(auto-fill, 100px) repeat(4, 1fr)

источник по repeat()

Примеры:

minmax() — функция

Позволяет задавать минимальное и максимальное значения для ряда/колонки. Используется в свойствах, где нужно задавать размер: grid-template-rows:, grid-template-columns:, grid-template:.

minmax( мин_значение, макс_значение )

Значение может быть:

  • px, em, rem, … — единицы длины (100px)
  • % — проценты (10%)
  • fr — гибкие размеры. Может использоваться только для макс. значения.

  • max-content — наименьший возможный размер ячейки, при котором содержимое свободно в ней умещается. Например, если в ячейке текст, идеальной шириной ячейки будет вся длина текста (в одну строку без переносов).

  • min-content — наименьший размер, при котором ячейка не переполняется. Например, если в ячейке текст то ширина будет равна самому длинному слову в тексте.

  • auto — зависит от того, используется оно как максимальное или минимальное значение в функции minmax():

    • если в качестве максимума, то тоже самое что max-content.
    • если в качестве минимума, то значение будет минимальным возможным размером для ячейки. Такой размер отличается от min-content и задается свойствами min-width или min-height.

Примеры:

Варианты использования:

grid-template-columns: minmax( 100px, 200px ) 1fr 1fr;
grid-template-columns: minmax( 200px, 50% ) 1fr 1fr;
grid-template-columns: minmax( 200px, 1fr ) 1fr 1fr;
grid-template-columns: minmax( min-content, max-content ) 1fr 1fr;
grid-template-columns: minmax( auto, auto ) 1fr 1fr;
grid-template-columns: repeat( auto-fit, minmax(200px, 1fr) );

Если указанное максимальное значение окажется меньше минимального, оно игнорируется и работает только мин. значение.

Подробное описание примеров смотрите в статье: как работает minmax().

grid-row-gap:
grid-column-gap:
grid-gap:

grid-row-gap: задает разрыв между рядами.
grid-column-gap: задает разрыв между колонками.
grid-gap: задает разрыв для рядов и колонок разом. Это сокращение для двух предыдущих свойств. Если указать один параметр он будет выставлен для обоих значений.

// синтаксис:
grid-row-gap: размер;
grid-column-gap: размер;

grid-gap: размер размер; /* row column */
grid-gap: размер;

Размер может быть абсолютным (px, pt), относительным (%, em).

Примеры:

grid-column-gap: 10px;
grid-row-gap: 15px;

Заметка: префикс grid- будет удален и названия свойств станут: column-gap: и row-gap:. Chrome 68+, Safari 11.2 и Opera 54+ уже поддерживают свойства без этого префикса.

align-content:
justify-content:
place-content:

Выравнивает ряды/колонки. Выравниваются ячейки сетки, не элементы внутри ячеек. Чтобы выровнять элементы, используйте: justify-items, align-items, place-items.

// синтаксис:
align-content:   значение;   // выравнивает ряды по вертикали ↓↑
justify-content: значение;   // выравнивает колонки по горизонтали ←→
place-content:   значение;   // сокращенная запись: установит оба значения
place-content:   align-content  justify-content; // сокращенная запись

Значение может быть:

  • stretch (default) — растягивает ряды/колонки (ячейки) полностью. Все пространство контейнера заполняется. Имеет смысл только если у рядов/колонок размер не задан жестко (они резиновые). Если они не резиновые, то работает как start.
  • start — ряды/колонки упакованы вплотную друг к другу к начальному краю контейнера.
  • end — ряды/колонки упакованы вплотную друг к другу к конечному краю контейнера.
  • center — ряды/колонки упакованы вплотную друг к другу и находятся по середине контейнера.

  • space-around — свободное пространство равномерно распределяется между рядами/колонками и добавляется по краям. Получается, что крайние ряд/колонка не прижимаются к краям контейнера, но расстояние до края в два раза меньше, чем между рядами/колонками.
  • space-evenly — тоже что и space-around, только расстояние до краев контейнера такое же как и между рядами/колонками.
  • space-between — крайние ряд/колонка прижимаются к краям контейнера и свободное место равномерно распределяется между рядами/колонками.

Редкие значения:

  • safe значение — если ширина колонки или высота ряда превышает размер контейнера, то значение переключается на start. В значении тут может быть только: center или end.

  • unsafe значение — значение остается указанным, даже если ширина колонки или высота ряда превышает размер контейнера. В значении тут может быть только: center или end.

    safe unsafe выравнивание

Примеры:

Полный синтаксис:

Выше для упрощения был не полный синтаксис, однако он покрывает 99% нужного.

// синтаксис:
align-content: normal | <distribution> | <overflow>? <position> | <baseline>
justify-content: normal | <distribution> | <overflow>? [ <position> | left | right ]

// <distribution> = space-between | space-around | space-evenly | stretch
// <overflow>     = unsafe | safe
// <position>     = center | start | end | flex-start | flex-end
// <baseline>     = [ first | last ]? baseline

// то что в [] или до ? — можно не указывать
  • left — для justify-content, не работает для align-content. Колонки упакованы вплотную друг к другу к левому краю контейнера.
  • right — для justify-content, не работает для align-content. Колонки упакованы вплотную друг к другу к правому краю контейнера.

  • flex-start — тоже что start для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как start.

  • flex-end — тоже что end для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как end.

  • baseline, first baseline, last baseline — выравнивает по линии текста (первой или последней). Обратная совместимость: для first baseline это start, для last baseline это end.

Все варианты значений:

align-content:

// базовое выравнивание
align-content: center;
align-content: start;
align-content: end;
align-content: flex-start;
align-content: flex-end;

align-content: normal;

// выравнивание по линии текста
align-content: baseline;
align-content: first baseline;
align-content: last baseline;

// распределение
align-content: space-between;
align-content: space-around;
align-content: space-evenly;
align-content: stretch;

// когда элемент перекрывает контейнер
align-content: safe center;
align-content: unsafe center;

// глобально
align-content: inherit;
align-content: initial;
align-content: unset;

justify-content:

// базовое выравнивание
justify-content: center;
justify-content: start;
justify-content: end;
justify-content: flex-start;
justify-content: flex-end;
justify-content: left;
justify-content: right;

align-content: normal;

// выравнивание по линии текста не имеет смысла

// распределение
justify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;
justify-content: stretch;

// когда элемент перекрывает контейнер
justify-content: safe center;
justify-content: unsafe center;

// глобально
justify-content: inherit;
justify-content: initial;
justify-content: unset;

place-content:

/* базовое выравнивание */
/* align-content не может быть left или right */
place-content: center start;
place-content: start center;
place-content: end left;
place-content: flex-start center;
place-content: flex-end center;

/* выравнивание по линии текста */
/* для второго параметра (justify-content) не имеет смысла */
place-content: baseline center;
place-content: first baseline space-evenly;
place-content: last baseline right;

/* распределение */
place-content: space-between space-evenly;
place-content: space-around space-evenly;
place-content: space-evenly stretch;
place-content: stretch space-evenly;

/* глобально */
place-content: inherit;
place-content: initial;
place-content: unset;
align-items:
justify-items:
place-items:

Выравнивает элементы сетки — то что находится внутри ячеек сетки. Срабатывает для всех элементов grid. Чтобы выровнять сами ячейки (ряды колонки), используйте: justify-content, align-content, place-content.

// синтаксис:
align-items: значение;    // выравнивает элементы по вертикали ↓↑
justify-items: значение;  // выравнивает элементы по горизонтали ←→
place-items: значение;    // сокращенная запись: установит оба значения
place-items: align-items  justify-items; // сокращенная запись

Значение может быть:

  • auto (default) — указывает использовать значение justify-items:, которое задается для контейнера. Если элемент позиционирован через absolute, то применяется normal.

  • stretch — растягивает все элементы на всю ширину/высоту ячеек.
  • start — размещает все элементы в начале ячеек (слева или сверху).
  • end — размещает все элементы в конце ячеек (справа или внизу).
  • center — размещает все элементы по центру ячеек.

Редкие значения:

  • safe значение — если ширина или высота элемента превышает размер ячейки, то значение переключается на start. В значении тут может быть только: center или end.

  • unsafe значение — значение остается указанным, даже если ширина или высота элемента превышает размер ячейки. В значении тут может быть только: center или end.

    safe unsafe выравнивание

Примеры:

Полный синтаксис:

Выше для упрощения был не полный синтаксис, однако он покрывает 99% нужного.

// синтаксис:
align-items: normal | stretch | [ <overflow>? <position> ] | <baseline>
justify-items: normal | stretch | <overflow>? [ <position> | left | right ] | <baseline> | legacy [ left | right | center ]

// <baseline> = [ first | last ]? baseline
// <overflow> = unsafe | safe
// <position> = center | start | end | self-start | self-end | flex-start | flex-end

// то что в [] или до ? — можно не указывать
  • left — для justify-items, не работает для align-items. Все элементы прижимаются к левому краю ячеек.
  • right — для justify-items, не работает для align-items. Все элементы прижимаются к правому краю ячеек.

  • flex-start — тоже что start для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как start.

  • flex-end — тоже что end для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как end.

  • baseline, first baseline, last baseline — выравнивает по линии текста (первой или последней). Обратная совместимость: для first baseline это start, для last baseline это end.

  • legacy — позволяет управлять тем, как будет наследоваться значение детьми.
    Если legacy указано без left, right, center, то значение просто наследуется у родителя или равно normal.
    Когда justify-self:auto ссылается на значение justify-items:, берется значение без слова legacy, например у legacy left будет взято left. Это нужно для правильного выравнивания тега <center> или элемента с атрибутом align.

Все варианты значений:

align-items:

// базовые значения
align-items: normal;
align-items: stretch;

// выравнивание позиции
// align-items не может быть left или right
align-items: center;
align-items: start;
align-items: end;
align-items: flex-start;
align-items: flex-end;
align-items: self-start;
align-items: self-end;

// выравнивание по линии текста
align-items: baseline;
align-items: first baseline;
align-items: last baseline;

// когда элемент перекрывает контейнер
align-items: safe center;
align-items: unsafe center;

// глобально
align-items: inherit;
align-items: initial;
align-items: unset;

justify-items:

// базовые значения
justify-items: auto;
justify-items: normal;
justify-items: stretch;

// выравнивание позиции
justify-items: center;
justify-items: start;
justify-items: end;
justify-items: flex-start;
justify-items: flex-end;
justify-items: self-start;
justify-items: self-end;
justify-items: left;
justify-items: right;

// выравнивание по линии текста
justify-items: baseline;
justify-items: first baseline;
justify-items: last baseline;

// когда элемент перекрывает контейнер
justify-items: safe center;
justify-items: unsafe center;

// выравнивание с приоритетом заимствования значения у родителя
justify-items: legacy right;
justify-items: legacy left;
justify-items: legacy center;

// глобально
justify-items: inherit;
justify-items: initial;
justify-items: unset;

place-items:

// базовые значения
place-items: auto center;
place-items: normal start;

// выравнивание позиции
place-items: center normal;
place-items: start auto;
place-items: end normal;
place-items: self-start auto;
place-items: self-end normal;
place-items: flex-start auto;
place-items: flex-end normal;
place-items: left auto;
place-items: right normal;

// выравнивание по линии текста
place-items: baseline normal;
place-items: first baseline auto;
place-items: last baseline normal;
place-items: stretch auto;

// глобально
place-items: inherit;
place-items: initial;
place-items: unset;
grid-auto-rows:
grid-auto-columns:

Устанавливает размер для авто-создаваемых (неявных) рядов/колонок.

Колонки/ряды создаются автоматически, когда в сетке элементов больше чем помещается в определенные ряды/колонки (ячейки) или когда элемент размещается за пределы указанной сетки.

// синтаксис:
grid-auto-columns: размер;
grid-auto-rows: размер;

Возможные значения размеров смотрите в описании grid-template-rows: и grid-template-columns: — может быть px, em, %, fr и т.д.

Примеры:

Чтобы понять как создаются авто-ячейки сетки, давайте представим что у нас есть сетка 2×2 — 2 ряда и 2 колонки:

grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px

Теперь, попробуем разместить элементы в сетку указав им позиции через свойства:

.item-a {
	grid-column: 1;
	grid-row: 2;
}
.item-b {
	grid-column: 5;
	grid-row: 2;
}

Элемент .item-b мы попросили разместиться в несуществующей колонке 5. У нас только 2 колонки, поэтому сетка автоматически расшириться и ей будут добавлены еще 3 колонки с auto шириной. Текущие свойства позволяют нам задать размеры для таких неявных колонок:

grid-auto-columns: 60px;

Интересный момент для неявных колонок рядов и repeat():

grid-auto-flow:

Определяет логику добавления элементов в пустые ячейки.

Когда элементам конкретно не указано в какой ячейке (области) они должны быть расположены, то они размещаются в пустые ячейки. По умолчанию заполнение идет слева направо (→) до конца ряда, переход на следующий ряд и опять заполнение (похоже на то как мы читаем текст).

По умолчанию алгоритм row т.е. такой → ↓ →, можно сделать так ↓ → ↓.

// синтаксис:
grid-auto-flow: row | column | row dense | column dense
  • row (default) — расставляет элементы в сетке по рядам → ↓ →. Добавляет ряды если в сетке нет места.

  • column — расставляет элементы в сетке по колонкам ↓ → ↓. Добавляет колонки если в сетке нет места.

  • dense — включает «dense» алгоритм заполнения, который пытается разместить элементы так, чтобы не оставалось пустых пространств (по умолчанию работает алгоритм «sparse»). При этом элементы могут располагаться не по-порядку. При вставке каждого следующего элемента, алгоритм проверяет нет ли пустой ячейки сзади куда может поместиться текущий элемент, если есть, помещает его туда а не в следующую ячейку. dense имеет смысл только при наличии областей в сетке — это когда элементу указано разместиться сразу в несколько ячеек (через span), тогда он как правило не помещается в одну ячейку и остается пустое место.

Примеры:

Допустим у нас есть такой HTML:

<div class="grid">
  <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>
</div>

Теперь, мы создали сетку с 5-ю колонками и двумя рядами и два элемента расположили в конкретные ячейки:

.grid {
	display: grid;
	grid-template: 60px 60px 60px 60px 60px / 30px 30px;
	/* по умолчанию: grid-auto-flow: row; */
}

Теперь установим grid-auto-flow: column:

grid:

Позволяет сокращенно записать свойства:

  • grid-template-rows:
  • grid-template-columns:
  • grid-template-areas:
  • grid-auto-rows:
  • grid-auto-columns:
  • grid-auto-flow:

Т.е. в этом свойстве можно описать почти все свойства грид-сетки. Однако, тут можно описать свойства только для «явных» или «неявных» рядов/колонок, сразу для тех и других не получиться. Если нужно указать свойства для тех и других, то нужно дописывать соответствующие свойства в дополнении к grid:.

// синтаксис:
grid: none
grid: grid-template
grid: grid-template-rows / grid-template-columns
grid: grid-template-areas
grid: grid-template-rows / [auto-flow dense?] grid-auto-columns?
grid: [auto-flow dense?] grid-auto-rows? / grid-template-columns

// то что в [] или до ? — можно не указывать
  • none — устанавливает все свойства в начальное состояние.

  • grid-template-rows / [auto-flow +dense?] grid-auto-columns? — ключевое слово auto-flow с правой стороны слэша устанавливает grid-auto-flow: column. dense включает алгоритм упаковки «dense». Если не указан grid-auto-columns, то он будет равен auto.

  • [auto-flow +dense?] grid-auto-rows? / grid-template-columns — ключевое слово auto-flow с левой стороны слэша устанавливает grid-auto-flow: row. dense включает алгоритм упаковки «dense». Если не указан grid-auto-rows, то он будет равен auto.

Примеры:

grid: 'header header header header'
	  'main main main right right'
	  'footer footer footer footer';

// тоже что:
grid-template-areas: 'header header header header'
					 'main main main right right'
					 'footer footer footer footer';
grid: 100px 300px / 3fr 1fr;

// тоже что:
grid-auto-flow: row;
grid-template-columns: 200px 1fr;
grid: auto-flow dense 100px / 1fr 2fr;

// тоже что:
grid-auto-flow: row dense;
grid-auto-rows: 100px;
grid-template-columns: 1fr 2fr;
grid: 100px 300px / auto-flow 200px;

// тоже что:
grid-template-rows: 100px 300px;
grid-auto-flow: column;
grid-auto-columns: 200px;

Также можно указать более сложный, но удобный для настройки все и сразу:

grid: [row1-start] "header header header" 1fr [row1-end]
	  [row2-start] "footer footer footer" 25px [row2-end]
	  /             auto   50px   auto;

// тоже что:
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: repeat(auto-fill, 5em) / auto-flow 1fr;
grid: auto-flow 1fr / repeat(auto-fill, 5em);
grid: auto 1fr auto / repeat(5, 1fr);
grid: repeat(3, auto) / repeat(4, auto);

Для элементов

CSS свойства: float, display:inline-block, display:table-cell, vertical-align и column-* никак не влияют на элементы grid контейнера. У grid сетки свои правила…

grid-row-start:
grid-row-end:
grid-column-start:
grid-column-end:
grid-row:
grid-column:

Указывает положение элемента в сетке. Т.е. размещает элемент в указанную ячейку. Указывать нужно имя или номер линии к которой относится ячейка и к которой нужно прикрепить элемент.

grid-column и grid-row — это сокращение для свойств: grid-column-start/grid-column-end и grid-row-start / grid-row-end. Можно указать только первое (одно) значение, оно будет относиться к начальной линии и элемент будет растягиваться на 1 ряд/колонку (т.е. будет помещен в одну ячейку начальная линия которой указана).

// синтаксис:
grid-row-start: значение;      // где начинается линия ряда
grid-row-end:   значение;      // где кончается линия ряда

grid-column-start: значение;   // где начинается линия колонки
grid-column-end:   значение;   // где кончается линия колонки

grid-row:    grid-row-start    / grid-row-end;
grid-column: grid-column-start / grid-column-end;

// можно указать одно значение, второе значение будет span 1
grid-row:    grid-row-start;
grid-column: grid-column-start;

Значение может быть:

  • число/имя — порядковый номер или имя линии к которой нужно прикрепить текущий элемент.

  • span число — слово span значит растянуть. Текущий элемент будет растягиваться на указанное число рядов/колонок. Если указано слово span, то относится всегда ко второму значению.

  • span имя — слово span значит растянуть. Текущий элемент будет растягиваться до указанного названия линии ряда/колонки. Если указано слово span, то относится всегда ко второму значению.

  • auto — элемент размещается по указанному алгоритму в свойстве контейнера grid-auto-flow:.

Примеры:

.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 ряд/колонку.

Элементы могут перекрывать друг друга, в таких случаях приоритет можно выставить через z-index:.

Пример сокращенного указания линий.

grid-column: 3 / span 2;
grid-row: third-line / 4;

grid-area:

Дает элементу имя. По имени элемент будет относится к области указанной в свойстве grid-template-areas:. Или в значении можно указать номер/имя линий.

// синтаксис:
grid-area: имя области;
grid-area: row-start / column-start / row-end / column-end;
  • имя области — название области сетки.
  • row-start / column-start / row-end / column-end — может быть числом или именем линии.

Примеры:

grid-area: header;

// или так:
grid-area: 1 / col4-start / last-line / 6

align-self:
justify-self:
place-self:

Выравнивает текущий элемент внутри ячейки. Применяется к отдельному элементу контейнера.

// синтаксис:
align-self:   значение;  // выравнивает элемент внутри ячейки по вертикали ↓↑
justify-self: значение;  // выравнивает элемент внутри ячейки по горизонтали ←→
place-self:   значение;  // сокращенная запись: установит оба значения
place-self:   align-self  justify-self; // сокращенная запись

Значение может быть:

  • stretch (defailt) — растягивает текущий элемент на всю ширину/высоту ячейки.
  • start — размещает текущий элемент в начале ячейки (слева или сверху).
  • end — размещает текущий элемент в конце ячейки (справа или внизу).
  • center — размещает текущий элемент по центру ячейки.

Редкие значения:

  • safe значение — если ширина или высота элемента превышает размер ячейки, то значение переключается на start. В значении тут может быть только: center или end.

  • unsafe значение — значение остается указанным, даже если ширина или высота элемента превышает размер ячейки. В значении тут может быть только: center или end.

Примеры:

Чтобы выровнять все элементы контейнера сразу, используйте: align-items:, justify-items:, place-items:. Там же вы найдете описание для редко-используемых значений.

Примеры

# Каркас HTML страницы

body {
	display: grid;
	grid: "header header  header" 80px
		  "nav    section aside"  1fr
		  "footer footer  footer" 50px
		  / 15%   1fr     18%;

	min-height: 100vh;
}

header  { grid-area: header;  }
nav     { grid-area: nav;     }
section { grid-area: section; }
aside   { grid-area: aside;   }
footer  { grid-area: footer;  }
<body>
	<header>header</header>
	<nav>nav</nav>
	<section>section</section>
	<aside>aside</aside>
	<footer>footer</footer>
</body>

# Каркас для игрового приложения

#grid {
  /**
   * Две колонки:
   *  1. подстраивается под контент,
   *  2. получает все оставшееся пространтсов
   *     (но не может быть меньше минимального размера контента в ней
		  или controls блока в этой же колонке)
   *
   * Три ряда:
   *  1. подстраивается под контент,
   *  2. получает все свободное пространство
   *     (но не может быть меньше минимального размера любого из блоков в этмо ряду)
   *  3. подстраивается под контент.
   */
  display: grid;
  grid-template-columns:
	/* 1 */ auto
	/* 2 */ 1fr;
  grid-template-rows:
	/* 1 */ auto
	/* 2 */ 1fr
	/* 3 */ auto;
  /* растянем на всю высоту */
  height: 100vh;
}

/* указывает позиции блоков в сетке с помощью координат */
#title    { grid-column: 1; grid-row: 1; }
#score    { grid-column: 1; grid-row: 3; }
#stats    { grid-column: 1; grid-row: 2; }
#board    { grid-column: 2; grid-row: 1 / span 2; }
#controls { grid-column: 2; grid-row: 3; justify-self: center; }
<div id="grid">
  <div id="title">Game Title</div>
  <div id="score">Score</div>
  <div id="stats">Stats</div>
  <div id="board">Board</div>
  <div id="controls">Controls</div>
</div>

Усложним задачу.

Теперь нам нужно сделать так чтобы при повороте мобильного устройства, каркас менялся и получалось так:

В этом случае удобнее будет использовать области Grid сетки.

/* книжная ориентация */
@media (orientation: portrait) {
	#grid {
	display: grid;

		/* создадаим структуру сетки и укажем названия областей,
		 * Такая структура будет работать по умолчанию и подоходиь для альбомной ориентации.
		 */
		grid-template-areas: "title stats"
							 "score stats"
							 "board board"
							 "ctrls ctrls";

		/* укажем размеры для рядов и колонок. */
		grid-template-columns: auto 1fr;
		grid-template-rows: auto auto 1fr auto;

		height: 100vh;
	}
}

/* альбомная ориентация */
@media (orientation: landscape) {
	#grid {
		display: grid;

		/* создадаим структуру сетки и укажем названия областей,
		 * Такая структура будет работать по умолчанию и подоходиь для альбомной ориентации.
		 */
		grid-template-areas: "title board"
							 "stats board"
							 "score ctrls";

		/* укажем размеры для рядов и колонок. */
		grid-template-columns: auto 1fr;
		grid-template-rows: auto 1fr auto;

		height: 100vh;
	}
}

/* расположим элементы в именованные областя сетки */
#title    { grid-area: title; }
#score    { grid-area: score; }
#stats    { grid-area: stats; }
#board    { grid-area: board; }
#controls { grid-area: ctrls; justify-self: center; }
<div id="grid">
  <div id="title">Game Title</div>
  <div id="score">Score</div>
  <div id="stats">Stats</div>
  <div id="board">Board</div>
  <div id="controls">Controls</div>
</div>

Этот пример нужно просмотреть с телефона…

# Простой блок на Grid

# Масонри на Грид

Совсем без JS никак еще пока.

Сравнение Flex и Grid

В отличие от Flex, которая ориентирована на одну ось, Grid оптимизирована для двумерных компоновок: когда требуется расположить (выровнять) содержимое в обоих измерениях (по вертикали и горизонтали).

Кроме того, благодаря возможности явного позиционирования элементов в сетке, Grid позволяет выполнять кардинальные преобразования в структуре, не требуя никаких изменений HTML разметки. Комбинируя медиа-запросы со свойствами CSS, управляющими компоновкой контейнера grid и его дочерних элементов, можно адаптировать верстку под любые форм-факторы устройств.

Grid и Flexbox, имеют свои особенности и нельзя сказать, что одно заменяет другое. Скорее Флекс является дополнением к Грид, или наоборот.

Flexbox фокусируется на распределении пространства внутри одной оси, использует более простой подход к компоновке, может использовать систему упаковки строк на основе размера содержимого для управления своей вторичной осью и полагается на иерархию разметки. Тогда как Grid больше подходит для создания каркасов, потому что имеет более мощный и комплексный подход и в целом не зависит от иерархии разметки. В отдельных случаях Grid позволяет создать адаптивный макет, который невозможно создать с помощью Flex или как-то еще.

Поддержка браузерами

Grid поддерживается {percent} браузерами, которые используются сегодня.

Чтобы проверить в css поддерживает ли текущий браузер Grid, можно использовать @supports (в IE не работает):

@supports( display: grid ) {
	/* grid поддерживается браузером */
	div { display: grid; }
}

@supports not( display: grid ) {
	/* grid НЕ поддерживается браузером */
	div { display: flex; }
}

Видео по Grid

Ссылки

Полезные ссылки по Grid:

  • Гриды на грядках — игра позволяет с интересом попрактиковаться с гридами.

  • grid.layoutit.com — интерактивный генератор грид сетки.

Использовал при написании:

  • https://www.w3.org/TR/css-grid-1/ (англ.)

  • Гид по гридам (css-tricks.com) (англ.)

  • Большая статься про гриды (css-live.ru)

  • CSS Grid (developer.mozilla.org)

  • CSS Grid Layout. Быстрый старт (habrahabr.ru)

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Как изменить высокоскоростное подключение на обычное
  • Как изменить вырез лодочка на платье
  • Как изменить вырез камеры на samsung а32
  • Как изменить вырез камеры на samsung a51
  • Как изменить вырез горловины на свитере

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии