Grid в CSS

Оглавление

Развернуть ▾

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

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

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

Чтобы разобраться с Грид-сеткой нужно понять из чего конкретно состоит эта сетка:

<title>Схема Grid-сетки</title>

<input type="checkbox" id="container" checked="checked" />
<label for="container">Grid контеинер</label>
<input type="checkbox" style="opacity:0;" /> <label></label>
<br>
<input type="checkbox" id="cells" checked="checked" />
<label for="cells">Ячейки (cell)</label>
<input type="checkbox" id="areas" />
<label for="areas">Области (поля, area)</label>
<br>
<input type="checkbox" id="rows" />
<label for="rows">Ряды, строки (row-track)</label>
<input type="checkbox" id="columns" />
<label for="columns">Колонки (column-track)</label>
<br>
<input type="checkbox" id="lines" checked="checked" />
<label for="lines">Линии (line, -start, -end)</label>
<input type="checkbox" id="gaps" />
<label for="gaps">Разрыв (gap)</label>
<br>

<div class="grid">
	<div class="cell"></div>
	<div class="cell"></div>
	<div class="cell"></div>

	<div class="cell"></div>
	<div class="cell"></div>
	<div class="cell"></div>

	<div class="cell"></div>
	<div class="cell"></div>
	<div class="cell"></div>

	<div class="area area1"></div>
	<div class="area area2"></div>

	<main class="row"></main>
	<main class="row"></main>
	<main class="row"></main>

	<main class="column"></main>
	<main class="column"></main>
	<main class="column"></main>
	
	<nav class="gap-row"></nav>
	<nav class="gap-row"></nav>
	<nav class="gap-col"></nav>
	<nav class="gap-col"></nav>

	<section class="line-row"><i>1</i><i>-4</i></section>
	<section class="line-row"><i>2</i><i>-3</i></section>
	<section class="line-row"><i>3</i><i>-2</i></section>
	<section class="line-row"><i>4</i><i>-1</i></section>
	
	<section class="line-col"><i>1</i><i>-4</i></section>
	<section class="line-col"><i>2</i><i>-3</i></section>
	<section class="line-col"><i>3</i><i>-2</i></section>
	<section class="line-col"><i>4</i><i>-1</i></section>
	
	<article class="container"></article>

</div>
body {
	font: 14px/1 sans-serif;
	color: #000;
	margin:0;
	text-align:center;
}

:root {
	--container-color: #777;
	--cell-color: #8488ab;
	--area-color: rgba(255, 128, 215, 0.4);
	--column-color: rgba(128, 210, 60, 0.4);
	--row-color: rgba(1, 183, 255, 0.4);
	--gap-color: #fbff9e;
	--line-color: #000;
}

input{ display: inline-block;  }
label{ display: inline-block; width:180px; vertical-align: top; cursor:pointer; padding:.3em; user-select:none; text-align:left; }
#cells:not(:checked) ~ .grid .cell,
#areas:not(:checked) ~ .grid .area,
#rows:not(:checked) ~ .grid .row,
#columns:not(:checked) ~ .grid .column,
#lines:not(:checked) ~ .grid .line-row,
#lines:not(:checked) ~ .grid .line-col,
#gaps:not(:checked) ~ .grid .gap-row,
#gaps:not(:checked) ~ .grid .gap-col,
#container:not(:checked) ~ .grid .container {
	display: none;
}

#container:checked + label{ background: var(--container-color); color:#fff; }
#rows:checked + label{ background: var(--row-color); }
#columns:checked + label{ background: var(--column-color); }
#cells:checked + label{ background: var(--cell-color); color:#fff; }
#areas:checked + label{ background: var(--area-color); }
#lines:checked + label{ background: var(--line-color); color:#fff; }
#gaps:checked + label{ background: var(--gap-color); }

.grid {
	display: grid;
	grid: 15px   65px 65px 65px   15px /  15px   150px  150px 150px   15px;
	grid-auto-rows: 15px;
	grid-auto-columns: 15px;
	grid-gap: 10px;
	margin:2em auto 0;
	width: 530px;
}

.container{ outline:5px solid var(--container-color); grid-row: 2 / 5; grid-column: 2 / 5; }

.cell { background: var(--cell-color); z-index: 1; }
.cell:nth-child(1) {  grid-row: 2; grid-column: 2; }
.cell:nth-child(2) {  grid-row: 2; grid-column: 3; }
.cell:nth-child(3) {  grid-row: 2; grid-column: 4; }

.cell:nth-child(4) {  grid-row: 3; grid-column: 2; }
.cell:nth-child(5) {  grid-row: 3; grid-column: 3; }
.cell:nth-child(6) {  grid-row: 3; grid-column: 4; }

.cell:nth-child(7) {  grid-row: 4; grid-column: 2; }
.cell:nth-child(8) {  grid-row: 4; grid-column: 3; }
.cell:nth-child(9) {  grid-row: 4; grid-column: 4; }

.area{ background: var(--area-color); z-index: 30; }
.area1 { grid-column: 2 / span 2; grid-row: 2; }
.area2 { grid-column: 3 / span 2; grid-row: 3 / span 2; }

/* rows */
.row {
	background: var(--row-color);
	grid-column: 1 / 6;
	z-index: 3;
}
.column {
	background: var(--column-color);
	grid-row: 1 / 6;
	z-index: 3;
}

.row:nth-of-type(1) { grid-row: 2; } 
.row:nth-of-type(2) { grid-row: 3; } 
.row:nth-of-type(3) { grid-row: 4; }
.column:nth-of-type(4) { grid-column: 2; } 
.column:nth-of-type(5) { grid-column: 3; } 
.column:nth-of-type(6) { grid-column: 4; }

/* gap */
.gap-row, .gap-col{ z-index:20; background: var(--gap-color); }
.gap-row {
	grid-column: 2 / 5;
	margin-top: -10px;
	height: 10px;
}
.gap-col {
	grid-row: 2 / 5;
	width: 10px;
	margin-left: -10px;
}

.gap-row:nth-of-type(1) { grid-row: 3; }
.gap-row:nth-of-type(2) { grid-row: 4; }
.gap-col:nth-of-type(3) { grid-column: 3; }
.gap-col:nth-of-type(4) { grid-column: 4; }

/* lines */
.line-row, .line-col{ z-index:40; }
.line-row i{ margin-left:-1em; }
.line-row i:last-child{ margin-right:-1em; }
.line-col i{ margin-top:-1em; }
.line-col i:last-child{ margin-bottom:-1em; }
.line-row{
	grid-column: 1 / 6; 
	margin-top: -10px;
	height:8px;
	border:1px solid var(--line-color); border-left:0; border-right:0;
	display: flex;
	justify-content: space-between;
	align-items: center;
}

.line-col{
	grid-row: 1 / 6;
	margin-left: -10px;
	width:8px;
	border:1px solid var(--line-color); border-top:0; border-bottom:0;
	display: flex;
	flex-flow: column;
	justify-content: space-between;
	align-items: center;
}
.line-row:nth-of-type(1) { grid-row: 2; border-top:0; margin-top: -9px; }
.line-row:nth-of-type(2) { grid-row: 3; }
.line-row:nth-of-type(3) { grid-row: 4; }
.line-row:nth-of-type(4) { grid-row: 5; border-bottom:0; }

.line-col:nth-of-type(5) { grid-column: 2; border-left:0; margin-left: -9px; }
.line-col:nth-of-type(6) { grid-column: 3; }
.line-col:nth-of-type(7) { grid-column: 4; }
.line-col:nth-of-type(8) { grid-column: 5; border-right:0; }

Описание Грид сетки

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

body {font: 14px Verdana, sans-serif;}
.grid, .inline-grid {
  border: 3px dashed #333;
  grid-gap: 3px 5px;
  margin: 15px 0;
}
.grid {
  display: grid;
}
.inline-grid {
  display: inline-grid;
}
.grid-item {
   border: 3px solid #aaccdd;
   border-radius: 5px;
   padding: 10px;
   background: rgba(242,226,5,.8);
}
<title>display:grid</title>


<div class="grid">
	<div class="grid-item">display: grid</div>
</div>

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

<div class="grid">
   <div class="grid-item">1</div>
   <div class="grid-item">2</div>
</div>

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

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

В веб-дизайне очень часто встречается компоновка, состоящая из верхнего, бокового, основного и нижнего колонтитулов. Для этого можно использовать grid-свойства:

<title>Example</title>

<body>
  <header id="pageHeader">Header</header>
  <article id="mainArticle">Article</article>
  <nav id="mainNav">Nav</nav>
  <div id="siteAds">Ads</div>
  <footer id="pageFooter">Footer</footer>
</body>
body { 
  display: grid;
  grid-template-areas: 
    "header header header"
    "nav article ads"
    "footer footer footer";
  grid-template-rows: 80px 1fr 70px;  
  grid-template-columns: 20% 1fr 15%;
  grid-row-gap: 10px;
  grid-column-gap: 10px;
  height: 100vh;
  margin: 0;
  }  
/* Stack the layout on small devices/viewports. */
@media all and (max-width: 575px) {
  body { 
    grid-template-areas: 
      "header"
      "article"
      "ads"
      "nav"
      "footer";
    grid-template-rows: 80px 1fr 70px 1fr 70px;  
    grid-template-columns: 1fr;
 }
}
header, footer, article, nav, div {
  padding: 1.2em;
  background: gold;
  }
#pageHeader {
  grid-area: header;
  }
#pageFooter {
  grid-area: footer;
  }
#mainArticle { 
  grid-area: article;      
  }
#mainNav { 
  grid-area: nav; 
  }
#siteAds { 
  grid-area: ads; 
  } 

CSS свойства Grid для контейнера

display:

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

Синтаксис

display: grid | inline-grid;

Значения

grid
генерирует блочную сетку
inline-grid
генерирует встроенную сетку

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

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

В значении через пробелы указываются размеры: высота ряда (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 [последнее-имя].

У двух этих свойств есть сокращенные записи:

Пример

<title>grid-template-rows/columns</title>
<b>grid-template-rows:</b>      
<input type="radio"  name="r" id="rows1" checked /><label for="rows1">70px 70px</label>
<input type="radio"  name="r" id="rows2" /><label for="rows2">50px 50px 100px</label>
<input type="radio"  name="r" id="rows3" /><label for="rows3">1fr 1fr 1fr</label>
<input type="radio"  name="r" id="rows4"  /><label for="rows4">repeat(4, 1fr)</label>
<br>

<b>grid-template-columns:</b> 
<input type="radio" name="c" id="columns1" checked /><label for="columns1">50px 100px 50%</label>
<input type="radio" name="c" id="columns2" /><label for="columns2">1fr 2fr</label>
<input type="radio" name="c" id="columns3" /><label for="columns3">1fr 1fr</label>
<input type="radio" name="c" id="columns4" /><label for="columns4">repeat(4, 1fr)</label>
<br>

<div class="grid">
	<div class="item">1</div>
	<div class="item">2</div>
	<div class="item">3</div>
	<div class="item">4</div>
	<div class="item">5</div>
	<div class="item">6</div>
</div>
body { font: 14px/1 sans-serif; padding:1em; margin:0; }

.grid {
	display: grid;
	grid-gap: .5em;
	/* grid-template: 1fr 1fr 1fr / 1fr 1fr 1fr; */
	grid-auto-rows: 30px;
	grid-auto-columns: 30px;
	margin:1em 0 0;
	border: 1px dashed #aaa;
	min-height:200px;
	max-width:700px;
}
.item{
	border-radius:3px; 
	background:#a5b8d0;
	color:rgba(0,0,0,.5); font-size:150%;
	display:flex; justify-content:center; align-items:center;
}

input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:.3em 1em; user-select:none; text-align:left; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }

#rows1:checked ~ .grid{ grid-template-rows: 70px 70px; }
#rows2:checked ~ .grid{ grid-template-rows: 50px 50px 100px; }
#rows3:checked ~ .grid{ grid-template-rows: 1fr 1fr 1fr; }
#rows4:checked ~ .grid{ grid-template-rows: repeat(4, 1fr); }

#columns1:checked ~ .grid{ grid-template-columns: 50px 100px 50%; }
#columns2:checked ~ .grid{ grid-template-columns: 1fr 2fr; }
#columns3:checked ~ .grid{ grid-template-columns: 1fr 1fr; }
#columns4:checked ~ .grid{ grid-template-columns: repeat(4, 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
область не определена

Заметки:

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

Пример:

<title>grid-template-areas</title>
<div class="grid">
	<div class="header">header</div>
	<div class="main">main</div>
	<div class="menu">menu</div>
</div>
html { height:100%; }
body { font: 14px/1 sans-serif; margin:0; height:100%; }
.grid{ min-height:100%; }

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

/* красивости */
.header, .main, .menu{ 
	display:flex; align-items:center; justify-content:center;
	color:rgba(0,0,0,.2); font-size:200%; text-transform:uppercase;
}

.header { background: #b0e6ff; }
.main   { background: #92d9e2; }
.menu   { background: #88c2f1; }

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

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(<сколько раз повторять>, <что повторять>)
.

У нее два основных варианта:

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

  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 повторяется заранее неизвестная ширина).

Пример

<title>Пример 1</title>
<b>grid-template:</b>
<br>
<input type="radio"  name="a" id="al0"  />
<label for="al0">repeat(3, 1fr) / repeat(3, 1fr)</label><br>
<input type="radio"  name="a" id="al1"/>
<label for="al1">repeat(3, 70px) / repeat(3, 70px)</label><br>
<input type="radio"  name="a" id="al2" />
<label for="al2">repeat(auto-fill, 70px) / repeat(auto-fill, 70px)</label><br>
<input type="radio"  name="a" id="al3" />
<label for="al3">repeat(auto-fit, 70px)  / repeat(auto-fit, 70px) </label><br>
<input type="radio"  name="a" id="al4" />
<label for="al4">repeat(auto-fill, minmax(70px,1fr)) / repeat(auto-fill, minmax(70px,1fr))</label><br>
<input type="radio"  name="a" id="al5" checked/>
<label for="al5">repeat(auto-fit, minmax(70px,1fr)) / repeat(auto-fit, minmax(70px,1fr))</label><br>
<input type="radio"  name="a" id="al6" /><label for="al6"></label>
<input type="radio"  name="a" id="al7" /><label for="al7"></label>

<br>
<b>grid-auto-rows: </b>
<input type="radio"  name="au" id="au0" checked /><label for="au0">нет</label>
<input type="radio"  name="au" id="au1"  /><label for="au1">50px</label>

<div class="grid">
	<div class="item">1</div>
	<div class="item">2</div>
	<div class="item">3</div>
	<div class="item">4</div>
	<div class="item">5</div>
	<div class="item">6</div>
	<div class="item">7</div>
	<div class="item">8</div>
	<div class="item">9</div>
</div>
body { font: 14px/1 sans-serif; padding:1em; margin:0; max-width:700px; }
input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:.3em .8em; user-select:none; text-align:left; font-family:monospace; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }


.grid {
	display: grid;
	grid-gap:.5em;
	margin:1em 0 0;
	border:1px dashed #666;
	animation: resize 6s linear infinite alternate;
}
.item {
	background:#a5b8d0; color:rgba(0,0,0,.5); font-size:200%; border-radius:3px;
	display:flex; justify-content:center; align-items:center;
	border:1px solid #8393a7;
}

#au1:checked ~ .grid{ grid-auto-rows: 50px; }

#al0:checked ~ .grid{ grid-template: repeat(3, 1fr) / repeat(3, 1fr) }
#al1:checked ~ .grid{ grid-template: repeat(3, 70px) / repeat(3, 70px) }
#al2:checked ~ .grid{ grid-template: repeat(auto-fill, 70px) / repeat(auto-fill, 70px) }
#al3:checked ~ .grid{ grid-template: repeat(auto-fit, 70px)  / repeat(auto-fit, 70px) }
#al4:checked ~ .grid{ grid-template: repeat(auto-fill, minmax(70px,1fr)) / repeat(auto-fill, minmax(70px,1fr)); }
#al5:checked ~ .grid{ grid-template: repeat(auto-fit, minmax(70px,1fr)) / repeat(auto-fit, minmax(70px,1fr)); }
#al6:checked ~ .grid{  }
#al7:checked ~ .grid{  }

@keyframes resize { 
  0%, 15% { width: 300px; height: 70px;  }
  85%, 100% { width: 100%; height: 280px; }
}

minmax()

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

Синтаксис

minmax(min, max)

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

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

Примеры:

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

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) );

Пример Grid: minmax()

<title>Пример Grid: minmax()</title>

<b>grid-template-columns: </b><br>
<input type="radio"  name="col" id="col1" checked />
<label for="col1">minmax(100px, 300px) 1fr;</label><br>
<input type="radio"  name="col" id="col2" />
<label for="col2">minmax(200px, 80%) 1fr;</label><br>
<input type="radio"  name="col" id="col3" />
<label for="col3">minmax(200px, 1fr) 1fr;</label><br>
<input type="radio"  name="col" id="col4" />
<label for="col4">minmax(max-content, max-content) 1fr;</label><br>
<input type="radio"  name="col" id="col5" />
<label for="col5">minmax(min-content, min-content) 1fr;</label><br>
<input type="radio"  name="col" id="col6" />
<label for="col6">minmax(auto, auto) 1fr;</label><br>
<input type="radio"  name="col" id="col7" />
<label for="col7">repeat( auto-fit, minmax(200px, 1fr) );</label><br>

<div class="grid">
	<div class="item">С другой стороны постоянное информационно-пропагандистское обеспечение нашей деятельности </div>
	<div class="item"></div>
</div>
body { font: 14px/1.25 sans-serif; padding:1em; margin:0; max-width:700px; }
input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:0 .8em; user-select:none; text-align:left; font-family:monospace; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }

.grid {
	display: grid;
	grid-gap:.5em;
		
	margin:1em 0 0;
	border:1px dashed #666;
	animation: resize 6s linear infinite alternate;
}
.item {
	background:rgba(140, 160, 191, 0.7); color:rgba(0,0,0,.5); font-size:115%; border-radius:3px; padding:1em;
}

#col1:checked ~ .grid{ grid-template-columns: minmax(100px, 300px) 1fr; }
#col2:checked ~ .grid{ grid-template-columns: minmax(200px, 80%) 1fr; }
#col3:checked ~ .grid{ grid-template-columns: minmax(200px, 1fr) 1fr; }
#col4:checked ~ .grid{ grid-template-columns: minmax(max-content, max-content) 1fr; }
#col5:checked ~ .grid{ grid-template-columns: minmax(min-content, min-content) 1fr; }
#col6:checked ~ .grid{ grid-template-columns: minmax(auto, auto) 1fr; }
#col7:checked ~ .grid{ grid-template-columns: repeat( auto-fit, minmax(200px, 1fr) ); }

@keyframes resize { 
  0%, 15% { width: 100px; height: 70px;  }
  85%, 100% { width: 100%; height: 280px; }
}

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: и row-gap:. Chrome 68+, Safari 11.2 и Opera 54+ уже поддерживают свойства без этого префикса.

Пример

<title>Grid-Gap</title>

<b>grid-row-gap:</b>      
<input type="radio"  name="r" id="rgap0" /><label for="rgap0">нет</label>
<input type="radio"  name="r" id="rgap1" checked /><label for="rgap1">20px</label>
<input type="radio"  name="r" id="rgap2" /><label for="rgap2">3em</label>
<input type="radio"  name="r" id="rgap3" /><label for="rgap3">5%</label>
<br>
<b>grid-column-gap:</b> 
<input type="radio" name="c" id="cgap0" /><label for="cgap0">нет</label>
<input type="radio" name="c" id="cgap1" checked /><label for="cgap1">20px</label>
<input type="radio" name="c" id="cgap2" /><label for="cgap2">3em</label>
<input type="radio" name="c" id="cgap3" /><label for="cgap3">5%</label>
<br>
<b>grid-gap:</b>              
<input type="radio" name="d" id="gap0" checked /><label for="gap0">нет</label>
<input type="radio" name="d" id="gap1" /><label for="gap1">10px</label>
<input type="radio" name="d" id="gap2" /><label for="gap2">1em 3em</label>
<input type="radio" name="d" id="gap3" /><label for="gap3">20% 5%</label>
<br>

<div class="grid">
	<div class="item">1</div>
	<div class="item">2</div>
	<div class="item">3</div>
	<div class="item">4</div>
	<div class="item">5</div>
	<div class="item">6</div>
</div>
body { font: 14px/1 sans-serif; padding:1em; margin:0; }

.grid {
	display: grid;
	grid-template: 1fr 1fr / 1fr 1fr 1fr;
	margin:1em 0 0;
	border: 1px dashed #555;
	height:200px;
	max-width:500px;
}
.item{
	background:#a5b8d0; color:rgba(0,0,0,.5); font-size:200%;
	display:flex; justify-content:center; align-items:center;
}

input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:.3em 1em; user-select:none; text-align:left; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }

/* #rgap0:checked ~ .grid{ grid-row-gap: unset; } */
#rgap1:checked ~ .grid{ grid-row-gap: 20px; }
#rgap2:checked ~ .grid{ grid-row-gap: 3em; }
#rgap3:checked ~ .grid{ grid-row-gap: 5%; }

/* #cgap0:checked ~ .grid{ grid-column-gap: unset; } */
#cgap1:checked ~ .grid{ grid-column-gap: 20px; }
#cgap2:checked ~ .grid{ grid-column-gap: 3em; }
#cgap3:checked ~ .grid{ grid-column-gap: 5%; }

/* #gap0:checked ~ .grid{ grid-gap: unset; } */
#gap1:checked ~ .grid{ grid-gap: 10px; }
#gap2:checked ~ .grid{ grid-gap: 1em 3em; }
#gap3:checked ~ .grid{ grid-gap: 20% 5%; }

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

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

Синтаксис

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

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

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

Пример

<title>Grid: align/justify-content:</title>

<b>align-content:</b>  
<input type="radio"  name="a" id="al0" /><label for="al0">нет</label>
<input type="radio"  name="a" id="al1" checked /><label for="al1">stretch</label>
<input type="radio"  name="a" id="al2" /><label for="al2">start</label>
<input type="radio"  name="a" id="al3" /><label for="al3">end</label>
<input type="radio"  name="a" id="al4" /><label for="al4">center</label>
<input type="radio"  name="a" id="al5" /><label for="al5">space-around</label>
<input type="radio"  name="a" id="al6" /><label for="al6">space-evenly</label>
<input type="radio"  name="a" id="al7" /><label for="al7">space-between</label>
<br>

<b>justify-content:</b>
<input type="radio"  name="b" id="js0" /><label for="js0">нет</label>
<input type="radio"  name="b" id="js1" checked /><label for="js1">stretch</label>
<input type="radio"  name="b" id="js2" /><label for="js2">start</label>
<input type="radio"  name="b" id="js3" /><label for="js3">end</label>
<input type="radio"  name="b" id="js4" /><label for="js4">center</label>
<input type="radio"  name="b" id="js5" /><label for="js5">space-around</label>
<input type="radio"  name="b" id="js6" /><label for="js6">space-evenly</label>
<input type="radio"  name="b" id="js7" /><label for="js7">space-between</label>
<br>

<b>place-content:</b>  
<input type="radio"  name="c" id="pl0" checked/><label for="pl0">нет</label>
<input type="radio"  name="c" id="pl1" /><label for="pl1">center start</label>
<input type="radio"  name="c" id="pl2" /><label for="pl2">start center</label>
<input type="radio"  name="c" id="pl3" /><label for="pl3">end start</label>
<input type="radio"  name="c" id="pl4" /><label for="pl4">start end</label>
<input type="radio"  name="c" id="pl5" /><label for="pl5">space-between end</label>
<input type="radio"  name="c" id="pl6" /><label for="pl6">space-evenly space-evenly</label>
<br>

<div class="grid">
	<div class="item">1</div>
	<div class="item">2</div>
	<div class="item">3</div>
	<div class="item">4</div>
	<div class="item">5</div>
	<div class="item">6</div>
</div>
body { font: 14px/1 sans-serif; padding:1em; margin:0; }

.grid {
	display: grid;
	grid-template: auto auto / auto auto auto;
	/* grid-gap: 1em; */
	/* align-items:center; */
	margin:1em 0 0;
	border: 1px dashed #555;
	height:200px;
	max-width:500px;
	
}
.item{
	background:#a5b8d0; color:rgba(0,0,0,.5); font-size:200%;
	display:flex; justify-content:center; align-items:center;
	border:1px solid #8393a7;
	padding:.3em .7em; line-height:1;
}

input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:.3em .5em; user-select:none; text-align:left; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }


#al0:checked ~ .grid{  }
#al1:checked ~ .grid{ align-content: stretch; }
#al2:checked ~ .grid{ align-content: start; }
#al3:checked ~ .grid{ align-content: end; }
#al4:checked ~ .grid{ align-content: center; }
#al5:checked ~ .grid{ align-content: space-around; }
#al6:checked ~ .grid{ align-content: space-evenly; }
#al7:checked ~ .grid{ align-content: space-between; }

#js0:checked ~ .grid{  }
#js1:checked ~ .grid{ justify-content: stretch; }
#js2:checked ~ .grid{ justify-content: start; }
#js3:checked ~ .grid{ justify-content: end; }
#js4:checked ~ .grid{ justify-content: center; }
#js5:checked ~ .grid{ justify-content: space-around; }
#js6:checked ~ .grid{ justify-content: space-evenly; }
#js7:checked ~ .grid{ justify-content: space-between; }

#pl0:checked ~ .grid{  }
#pl1:checked ~ .grid{ place-content: center start; }
#pl2:checked ~ .grid{ place-content: start center; }
#pl3:checked ~ .grid{ place-content: end start; }
#pl4:checked ~ .grid{ place-content: start end; }
#pl5:checked ~ .grid{ place-content: space-between end; }
#pl6:checked ~ .grid{ place-content: space-evenly space-evenly; }

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

Выше для упрощения был не полный синтаксис, однако он покрывает 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

 то что в [] или до ? — можно не указывать */
Развернуть ▾

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; /* сокращенная запись */

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

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

Пример

<title>Grid: align/justify-items:</title>

<b>align-items:</b>  
<input type="radio"  name="a" id="al0" /><label for="al0">нет</label>
<input type="radio"  name="a" id="al1" /><label for="al1">stretch</label>
<input type="radio"  name="a" id="al2" /><label for="al2">start</label>
<input type="radio"  name="a" id="al3" /><label for="al3">end</label>
<input type="radio"  name="a" id="al4" checked /><label for="al4">center</label>
<input type="radio"  name="a" id="al5" /><label for="al5"></label>
<input type="radio"  name="a" id="al6" /><label for="al6"></label>
<input type="radio"  name="a" id="al7" /><label for="al7"></label>
<br>

<b>justify-items:</b>
<input type="radio"  name="b" id="js0" /><label for="js0">нет</label>
<input type="radio"  name="b" id="js1" /><label for="js1">stretch</label>
<input type="radio"  name="b" id="js2" /><label for="js2">start</label>
<input type="radio"  name="b" id="js3" /><label for="js3">end</label>
<input type="radio"  name="b" id="js4" checked /><label for="js4">center</label>
<input type="radio"  name="b" id="js5" /><label for="js5"></label>
<input type="radio"  name="b" id="js6" /><label for="js6"></label>
<input type="radio"  name="b" id="js7" /><label for="js7"></label>
<br>

<b>place-items:</b> 
<input type="radio"  name="c" id="pl0" checked/><label for="pl0">нет</label>
<input type="radio"  name="c" id="pl1" /><label for="pl1">center start</label>
<input type="radio"  name="c" id="pl2" /><label for="pl2">start center</label>
<input type="radio"  name="c" id="pl3" /><label for="pl3">end start</label>
<input type="radio"  name="c" id="pl4" /><label for="pl4">start end</label>
<input type="radio"  name="c" id="pl5" /><label for="pl5">stretch start</label>
<input type="radio"  name="c" id="pl6" /><label for="pl6">start stretch</label>
<br>

<div class="grid">
	<div class="item">1</div>
	<div class="item">2</div>
	<div class="item">3</div>
	<div class="item">4</div>
	<div class="item">5</div>
	<div class="item">6</div>
	
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
</div>
body { font: 14px/1 sans-serif; padding:1em; margin:0; }

input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:.3em .5em; user-select:none; text-align:left; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }


.grid {
	display: grid;
	grid-template: auto auto / auto auto auto;
	/* grid-gap: 1em; */
	/* align-items:center; */
	margin:1em 0 0;
	border: 1px dashed #555; border-bottom:0; border-right:0;
	height:200px;
	max-width:500px;
	
}
.item{
	background:#a5b8d0; color:rgba(0,0,0,.5); font-size:200%;
	display:flex; justify-content:center; align-items:center;
	border:1px solid #8393a7;
	padding:.3em .7em; line-height:1;
}

.cell{ 
	justify-self: stretch; align-self: stretch;
	border:1px dashed #555; border-top:0; border-left:0; width:100%; height:100%;
}


.cell:nth-of-type(1), .item:nth-of-type(1){ grid-row:1; grid-column:1; }
.cell:nth-of-type(2), .item:nth-of-type(2){ grid-row:1; grid-column:2; }
.cell:nth-of-type(3), .item:nth-of-type(3){ grid-row:1; grid-column:3; }
.cell:nth-of-type(4), .item:nth-of-type(4){ grid-row:2; grid-column:1; }
.cell:nth-of-type(5), .item:nth-of-type(5){ grid-row:2; grid-column:2; }
.cell:nth-of-type(6), .item:nth-of-type(6){ grid-row:2; grid-column:3; }


#al0:checked ~ .grid{  }
#al1:checked ~ .grid{ align-items: stretch; }
#al2:checked ~ .grid{ align-items: start; }
#al3:checked ~ .grid{ align-items: end; }
#al4:checked ~ .grid{ align-items: center; }
#al5:checked ~ .grid{ align-items: ___; }
#al6:checked ~ .grid{ align-items: ___; }
#al7:checked ~ .grid{ align-items: ___; }

#js0:checked ~ .grid{  }
#js1:checked ~ .grid{ justify-items: stretch; }
#js2:checked ~ .grid{ justify-items: start; }
#js3:checked ~ .grid{ justify-items: end; }
#js4:checked ~ .grid{ justify-items: center; }
#js5:checked ~ .grid{ justify-items: ___; }
#js6:checked ~ .grid{ justify-items: ___; }
#js7:checked ~ .grid{ justify-items: ___; }

#pl0:checked ~ .grid{  }
#pl1:checked ~ .grid{ place-items: center start; }
#pl2:checked ~ .grid{ place-items: start center; }
#pl3:checked ~ .grid{ place-items: end start; }
#pl4:checked ~ .grid{ place-items: start end; }
#pl5:checked ~ .grid{ place-items: stretch start; }
#pl6:checked ~ .grid{ place-items: start stretch; }

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

Выше для упрощения был не полный синтаксис, однако он покрывает 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

 то что в [] или до ? — можно не указывать  */
Развернуть ▾

grid-auto-rows:, grid-auto-columns:

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

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

grid-auto-columns: размер;
grid-auto-rows: размер;

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

Пример

<title>Grid: grid-auto-columns/rows:</title>

Выглядит как баг: высота в repeat() указываются жестко, но когда блоки не лезут в контейнер, их высота сжимается меньше указанного в repeat() размера. Однако grid-auto-rows влияет на эту высоту. А grid-auto-column ни на что не влияет!<br><br>
Так происходит, потому что repeat() не создает рядов/колонок больше чем лезет в блок, поэтому создаются неявные (auto) ряды. При этом неявные создаются только ряды и непоместившиеся блоки размещаются вниз.<br><br>
Но если изменить "течение" <b>grid-auto-flow</b> на <b>column</b>, то будет все тоже самое, только теперь непоместившиеся блоки размещаются в колонки (вправо).
<br>
<br>
<b>grid-template:</b> <code>repeat(auto-fit, 50px) / repeat(auto-fit, 50px);</code>
<br>
<b>grid-auto-flow: </b>
<input type="radio"  name="auf" id="auf0" checked /><label for="auf0">row</label>
<input type="radio"  name="auf" id="auf1" /><label for="auf1">column</label>
<br>
<b>grid-auto-rows: </b>
<input type="radio"  name="aur" id="aur0" checked /><label for="aur0">нет</label>
<input type="radio"  name="aur" id="aur1" /><label for="aur1">100px</label>
<br>
<b>grid-auto-column: </b>
<input type="radio"  name="auc" id="auc0" checked /><label for="auc0">нет</label>
<input type="radio"  name="auc" id="auc1" /><label for="auc1">100px</label>

<div class="grid">
	<div class="item">1</div>
	<div class="item">2</div>
	<div class="item">3</div>
	<div class="item">4</div>
	<div class="item">5</div>
	<div class="item">6</div>
	<div class="item">7</div>
	<div class="item">8</div>
	<div class="item">9</div>
</div>
body { font: 14px/1.25 sans-serif; padding:1em; margin:0; max-width:700px; }
input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:0 .8em; user-select:none; text-align:left; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }

.grid {
	display: grid;
	grid-gap:.5em;
	grid-template: repeat(auto-fit, 50px) / repeat(auto-fit, 50px);	
	margin:1em 0 0;
	border:1px dashed #666;
	animation: resize 6s linear infinite alternate;
}
.item {
	background:#a5b8d0; color:rgba(0,0,0,.5); font-size:200%; border-radius:3px;
	display:flex; justify-content:center; align-items:center;
	border:1px solid #8393a7;
}

#auf1:checked ~ .grid{ grid-auto-flow: column; }
#aur1:checked ~ .grid{ grid-auto-rows: 100px; }
#auc1:checked ~ .grid{ grid-auto-columns: 100px; }


@keyframes resize { 
  0%, 15% { width: 150px; height: 70px;  }
  85%, 100% { width: 100%; height: 280px; }
}

grid-auto-flow:

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

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

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

Синтаксис

grid-auto-flow: row | column | row dense | column dense

Значения

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

Пример

<title>Grid: grid-auto-flow</title>

<b>grid-auto-flow:</b>
<input type="radio" name="a" id="al1" checked /><label for="al1">row</label>
<input type="radio" name="a" id="al2" /><label for="al2">row dense</label>
<input type="radio" name="a" id="al3" /><label for="al3">column</label>
<input type="radio" name="a" id="al4" /><label for="al4">column dense</label>
<br>

<b>размеры элементов:</b>
<input type="radio" name="b" id="size1" /><label for="size1">разные</label>
<input type="radio" name="b" id="size2" checked /><label for="size2">одинаковые</label>
<br>

<div class="grid">
	<div class="item">1</div>
	<div class="item">2</div>
	<div class="item">3</div>
	<div class="item">4</div>
	<div class="item">5</div>
	<div class="item">6</div>
	<div class="item">7</div>
	<div class="item">8</div>
	<div class="item">9</div>
</div>
body { font: 14px/1 sans-serif; padding:1em; margin:0; }

input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:.3em .5em; user-select:none; text-align:left; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }


.grid {
	display: inline-grid;
	grid-template: 70px 70px 70px / 100px 100px 100px;
	grid-auto-rows: 70px;
	grid-auto-columns: 100px;
	grid-gap: 1em;
	
	padding:1em;
	margin:1em 0 0;
	background:#dae0e8;	
}
.item{
	background:#a5b8d0; color:rgba(0,0,0,.5); font-size:200%;
	display:flex; justify-content:center; align-items:center;
}

#size1:checked ~ .grid .item:nth-of-type(3){ grid-column: auto / span 2; }
#size1:checked ~ .grid .item:nth-of-type(5){ grid-row: span 2 / auto; }
#size1:checked ~ .grid .item:nth-of-type(7){ grid-row: span 2 / auto; }

#al1:checked ~ .grid{ grid-auto-flow: row; }
#al2:checked ~ .grid{ grid-auto-flow: row dense; }
#al3:checked ~ .grid{ grid-auto-flow: column; }
#al4:checked ~ .grid{ grid-auto-flow: column dense; }

grid:

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

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

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

Примеры:

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 свойства Grid для элементов

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:.

Пример

<title>Grid: grid-column/row:</title>

<b>grid-row-start:</b>      
<input type="radio" name="rs" id="rs0" /><label for="rs0">нет</label>
<input type="radio" name="rs" id="rs1" /><label for="rs1">1</label>
<input type="radio" name="rs" id="rs2" checked /><label for="rs2">2</label>
<input type="radio" name="rs" id="rs3" /><label for="rs3">3</label>
<input type="radio" name="rs" id="rs4" /><label for="rs4">4</label>
<br>

<b>grid-row-end:</b>       
<input type="radio" name="re" id="re0" checked /><label for="re0">нет</label>
<input type="radio" name="re" id="re1" /><label for="re1">1</label>
<input type="radio" name="re" id="re2" /><label for="re2">2</label>
<input type="radio" name="re" id="re3" /><label for="re3">3</label>
<input type="radio" name="re" id="re4" /><label for="re4">4</label>
<br>

<b>grid-column-start:</b>
<input type="radio" name="cs" id="cs0" /><label for="cs0">нет</label>
<input type="radio" name="cs" id="cs1" /><label for="cs1">1</label>
<input type="radio" name="cs" id="cs2" checked /><label for="cs2">2</label>
<input type="radio" name="cs" id="cs3" /><label for="cs3">3</label>
<input type="radio" name="cs" id="cs4" /><label for="cs4">4</label>
<input type="radio" name="cs" id="cs5" /><label for="cs5">5</label>
<input type="radio" name="cs" id="cs6" /><label for="cs6">6</label>
<br>

<b>grid-column-end:</b> 
<input type="radio" name="ce" id="ce0" checked /><label for="ce0">нет</label>
<input type="radio" name="ce" id="ce1" /><label for="ce1">1</label>
<input type="radio" name="ce" id="ce2" /><label for="ce2">2</label>
<input type="radio" name="ce" id="ce3" /><label for="ce3">3</label>
<input type="radio" name="ce" id="ce4" /><label for="ce4">4</label>
<input type="radio" name="ce" id="ce5" /><label for="ce5">5</label>
<input type="radio" name="ce" id="ce6" /><label for="ce6">6</label>
<br>

<b>grid-row:</b>              
<input type="radio" name="gr" id="gr0" checked /><label for="gr0">нет</label>
<input type="radio" name="gr" id="gr1" /><label for="gr1">2</label>
<input type="radio" name="gr" id="gr2" /><label for="gr2">1 / 3</label>
<input type="radio" name="gr" id="gr3" /><label for="gr3">1 / span 3</label>
<input type="radio" name="gr" id="gr4" /><label for="gr4">2 / span 2</label>
<br>

<b>grid-column:</b>        
<input type="radio" name="gc" id="gc0" checked /><label for="gc0">нет</label>
<input type="radio" name="gc" id="gc1" /><label for="gc1">2</label>
<input type="radio" name="gc" id="gc2" /><label for="gc2">1 / 3</label>
<input type="radio" name="gc" id="gc3" /><label for="gc3">2 / span 3</label>
<input type="radio" name="gc" id="gc4" /><label for="gc4">3 / span 2</label>
<br>

<div class="grid">
	<div class="item"></div>
	
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
	<nav class="cell"></nav>
</div>
body { font: 14px/1 sans-serif; padding:1em; margin:0; }

input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:.3em .5em; user-select:none; text-align:left; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }


.grid {
	display: grid;
	grid: repeat(3, 1fr) / repeat(5, 1fr);
	
	margin:1em 0 0;
	border: 1px dashed #555; border-bottom:0; border-right:0;
	height:250px; width:450px;
}
.item{
	background:rgba(46,85,113,0.32); color:rgba(0,0,0,.5); width:100%; height:100%;
	/* grid-column: 1 / span 2;
	grid-row: 2; */
	/* grid-column-start: 2; grid-column-end: 2;
	grid-row-start: 2; grid-row-end: 2; */
}

.cell{ 
	justify-self: stretch; align-self: stretch;
	border:1px dashed #555; border-top:0; border-left:0; width:100%; height:100%;
}
.cell:nth-of-type(1){ grid-row:1; grid-column:1; }
.cell:nth-of-type(2){ grid-row:1; grid-column:2; }
.cell:nth-of-type(3){ grid-row:1; grid-column:3; }
.cell:nth-of-type(4){ grid-row:1; grid-column:4; }
.cell:nth-of-type(5){ grid-row:1; grid-column:5; }
.cell:nth-of-type(6){ grid-row:2; grid-column:1; }
.cell:nth-of-type(7){ grid-row:2; grid-column:2; }
.cell:nth-of-type(8){ grid-row:2; grid-column:3; }
.cell:nth-of-type(9){ grid-row:2; grid-column:4; }
.cell:nth-of-type(10){ grid-row:2; grid-column:5; }
.cell:nth-of-type(11){ grid-row:3; grid-column:1; }
.cell:nth-of-type(12){ grid-row:3; grid-column:2; }
.cell:nth-of-type(13){ grid-row:3; grid-column:3; }
.cell:nth-of-type(14){ grid-row:3; grid-column:4; }
.cell:nth-of-type(15){ grid-row:3; grid-column:5; }


#cs0:checked ~ .grid .item{  }
#cs1:checked ~ .grid .item{ grid-column-start: 1 }
#cs2:checked ~ .grid .item{ grid-column-start: 2 }
#cs3:checked ~ .grid .item{ grid-column-start: 3 }
#cs4:checked ~ .grid .item{ grid-column-start: 4 }
#cs5:checked ~ .grid .item{ grid-column-start: 5 }
#cs6:checked ~ .grid .item{ grid-column-start: 6 }

#ce0:checked ~ .grid .item{  }
#ce1:checked ~ .grid .item{ grid-column-end: 1 }
#ce2:checked ~ .grid .item{ grid-column-end: 2 }
#ce3:checked ~ .grid .item{ grid-column-end: 3 }
#ce4:checked ~ .grid .item{ grid-column-end: 4 }
#ce5:checked ~ .grid .item{ grid-column-end: 5 }
#ce6:checked ~ .grid .item{ grid-column-end: 6 }

#rs0:checked ~ .grid .item{  }
#rs1:checked ~ .grid .item{ grid-row-start: 1 }
#rs2:checked ~ .grid .item{ grid-row-start: 2 }
#rs3:checked ~ .grid .item{ grid-row-start: 3 }
#rs4:checked ~ .grid .item{ grid-row-start: 4 }
#rs5:checked ~ .grid .item{ grid-row-start: 5 }
#rs6:checked ~ .grid .item{ grid-row-start: 6 }

#re0:checked ~ .grid .item{  }
#re1:checked ~ .grid .item{ grid-row-end: 1 }
#re2:checked ~ .grid .item{ grid-row-end: 2 }
#re3:checked ~ .grid .item{ grid-row-end: 3 }
#re4:checked ~ .grid .item{ grid-row-end: 4 }
#re5:checked ~ .grid .item{ grid-row-end: 5 }
#re6:checked ~ .grid .item{ grid-row-end: 6 }

#gc0:checked ~ .grid .item{  }
#gc1:checked ~ .grid .item{ grid-column: 2; }
#gc2:checked ~ .grid .item{ grid-column: 1 / 3; }
#gc3:checked ~ .grid .item{ grid-column: 2 / span 3; }
#gc4:checked ~ .grid .item{ grid-column: 3 / span 2; }

#gr0:checked ~ .grid .item{  }
#gr1:checked ~ .grid .item{ grid-row: 2; }
#gr2:checked ~ .grid .item{ grid-row: 1 / 3; }
#gr3:checked ~ .grid .item{ grid-row: 1 / span 3; }
#gr4:checked ~ .grid .item{ grid-row: 2 / span 2; }

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
по умолчанию. Растягивает текущий элемент на всю ширину/высоту ячейки.
start
размещает текущий элемент в начале ячейки (слева или сверху).
end
размещает текущий элемент в конце ячейки (справа или внизу).
center
размещает текущий элемент по центру ячейки.

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

safe значение

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

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

Пример

<title>Grid: align/justify-self:</title>

<b>align-self:</b>  
<input type="radio"  name="a" id="al0" /><label for="al0">нет</label>
<input type="radio"  name="a" id="al1" checked /><label for="al1">stretch</label>
<input type="radio"  name="a" id="al2" /><label for="al2">start</label>
<input type="radio"  name="a" id="al3" /><label for="al3">end</label>
<input type="radio"  name="a" id="al4" /><label for="al4">center</label>
<input type="radio"  name="a" id="al5" /><label for="al5"></label>
<input type="radio"  name="a" id="al6" /><label for="al6"></label>
<input type="radio"  name="a" id="al7" /><label for="al7"></label>
<br>

<b>justify-self:</b>
<input type="radio"  name="b" id="js0" /><label for="js0">нет</label>
<input type="radio"  name="b" id="js1" checked /><label for="js1">stretch</label>
<input type="radio"  name="b" id="js2" /><label for="js2">start</label>
<input type="radio"  name="b" id="js3" /><label for="js3">end</label>
<input type="radio"  name="b" id="js4" /><label for="js4">center</label>
<input type="radio"  name="b" id="js5" /><label for="js5"></label>
<input type="radio"  name="b" id="js6" /><label for="js6"></label>
<input type="radio"  name="b" id="js7" /><label for="js7"></label>
<br>

<b>place-self:</b> 
<input type="radio"  name="c" id="pl0" checked/><label for="pl0">нет</label>
<input type="radio"  name="c" id="pl1" /><label for="pl1">center start</label>
<input type="radio"  name="c" id="pl2" /><label for="pl2">start center</label>
<input type="radio"  name="c" id="pl3" /><label for="pl3">end start</label>
<input type="radio"  name="c" id="pl4" /><label for="pl4">start end</label>
<input type="radio"  name="c" id="pl5" /><label for="pl5">stretch start</label>
<input type="radio"  name="c" id="pl6" /><label for="pl6">start stretch</label>
<br>

<div class="grid">
	<div class="item">1</div>
	<div class="item">2</div>
	<div class="item">3</div>
	<div class="item">4</div>
	<div class="item">5</div>
	<div class="item">6</div>
</div>
body { font: 14px/1 sans-serif; padding:1em; margin:0; }

input{ display: none; }
label{ display: inline-block; cursor:pointer; padding:.3em .5em; user-select:none; text-align:left; }
label:hover{ background:#ccc; }
input:checked + label{ font-weight:bold; background:#ccc; }


.grid {
	display: grid;
	grid-template: auto auto / auto auto auto;
	/* grid-gap: 1em; */
	/* align-items:center; */
	margin:1em 0 0;
	border: 1px dashed #555; border-bottom:0; border-right:0;
	height:200px;
	max-width:500px;
	
}
.item{
	background:#a5b8d0; color:rgba(0,0,0,.5); font-size:200%;
	display:flex; justify-content:center; align-items:center;
	border:1px solid #8393a7;
	padding:.6em .9em; line-height:1;
}

.grid .item:nth-of-type(2){ background:#cae01b; border:1px solid #a0b116; }

#al0:checked ~ .grid .item:nth-of-type(2){  }
#al1:checked ~ .grid .item:nth-of-type(2){ align-self: stretch; }
#al2:checked ~ .grid .item:nth-of-type(2){ align-self: start; }
#al3:checked ~ .grid .item:nth-of-type(2){ align-self: end; }
#al4:checked ~ .grid .item:nth-of-type(2){ align-self: center; }
#al5:checked ~ .grid .item:nth-of-type(2){ align-self: ___; }
#al6:checked ~ .grid .item:nth-of-type(2){ align-self: ___; }
#al7:checked ~ .grid .item:nth-of-type(2){ align-self: ___; }

#js0:checked ~ .grid .item:nth-of-type(2){  }
#js1:checked ~ .grid .item:nth-of-type(2){ justify-self: stretch; }
#js2:checked ~ .grid .item:nth-of-type(2){ justify-self: start; }
#js3:checked ~ .grid .item:nth-of-type(2){ justify-self: end; }
#js4:checked ~ .grid .item:nth-of-type(2){ justify-self: center; }
#js5:checked ~ .grid .item:nth-of-type(2){ justify-self: ___; }
#js6:checked ~ .grid .item:nth-of-type(2){ justify-self: ___; }
#js7:checked ~ .grid .item:nth-of-type(2){ justify-self: ___; }

#pl0:checked ~ .grid .item:nth-of-type(2){  }
#pl1:checked ~ .grid .item:nth-of-type(2){ place-self: center start; }
#pl2:checked ~ .grid .item:nth-of-type(2){ place-self: start center; }
#pl3:checked ~ .grid .item:nth-of-type(2){ place-self: end start; }
#pl4:checked ~ .grid .item:nth-of-type(2){ place-self: start end; }
#pl5:checked ~ .grid .item:nth-of-type(2){ place-self: stretch start; }
#pl6:checked ~ .grid .item:nth-of-type(2){ place-self: start stretch; }
Чтобы выровнять все элементы контейнера сразу, используйте: align-items:, justify-items:, place-items:. Там же вы найдете описание для редко-используемых значений.

Примеры

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

<title>Пример 1</title>

<body>
	<header>header</header>
	<nav>nav</nav>
	<section>section</section>
	<aside>aside</aside>
	<footer>footer</footer>
</body>
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{ margin:0; font-family: sans-serif; }

body > *{ padding:1em; }

header  { background: #daebe8; }
nav     { background: #cfe0e8; }
section { background: #b7d7e8; }
aside   { background: #bccad6; }
footer  { background: #b3d4ce; }

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

<title>Пример 2</title>

<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 {
  /**
   * Две колонки:
   *  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; }

/* стили для наглядности */
body{ margin:0; font-family: sans-serif; }
#grid > *{ padding: 1em; }

#title    { background: #daebe8; }
#score    { background: #cfe0e8; }
#stats    { background: #b7d7e8; }
#board    { background: #bccad6; }
#controls { background: #b7d7e8; }

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

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

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

<title>Пример 3</title>

<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>
/* книжная ориентация */
@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; }


/* стили для наглядности */
body{ margin:0; font-family: sans-serif; }
#grid > *{ padding:1em; }

#title    { background: #daebe8; }
#score    { background: #cfe0e8; }
#stats    { background: #b7d7e8; }
#board    { background: #bccad6; }
#controls { background: #b7d7e8; }

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

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

<title>Пример 4</title>

<div class="support-grid"></div>

<section class="grid-1">

  <div class="panel panel-title">
    <h1>Barry’s Cushion</h2>
    <p>Сказка о летаргии и мягкой мебели</p>
  </div>
    <div class="panel panel-1"></div>
    <div class="panel panel-2"></div>
    <div class="panel panel-3">
      <p>“Наверное, мне пора вставать, есть дела.”</p>
    </div>
    <div class="panel panel-4"></div>
    <div class="panel panel-5"></div>
    <div class="panel panel-6"></div>
    <div class="panel panel-7">
      <p>“Naaah.”</p>
    </div>
    <div class="panel panel-8"></div>
    <div class="panel panel-9"></div>
    <div class="panel panel-copyright">
      <p>Sleepy Fat Cat by messenj4h<br>
          © Copyright happily ever after 
          <a target="_blank" href="https://webdesign.tutsplus.com/tutorials/css-grid-layout-and-comics-as-explained-by-barry-the-cat--cms-27617">Envato Tuts+</a>
    </div>
</section>
/* basics */
body {
  background: #f8f7f2;
  padding: 0 10%;
  font: 100%/1.5 'Kalam', cursive;
}

h1 {
  margin: 0;
  line-height: 1;
  padding: 10px;
  color: #251b19;
}

p {
  margin: 0;
  padding: 10px;
  color: #251b19;
  font-size: 1.2em;
}

a {
  color: #e56633;
}

a:hover {
  text-decoration: none;
}

/* the grid */
.grid-1 {
  display: grid;
  width: 100%;
  max-width: 770px;
  margin: 10% auto;
  grid-template-columns: 1fr;
  grid-template-rows: auto 200px 200px auto 200px 200px 200px auto 200px 200px auto;
  grid-gap: 25px;
}

/* panels */
.panel {
  color: white;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
  box-shadow: 0 0px 0px 5px #251b19;
}

/* individual panels */
.panel-title {
  box-shadow: none;
}
.panel-1 {
  background-image: url(cat/cat-002.svg);
  box-shadow: none;
}
.panel-2 {
  background-image: url(cat/cat-001.svg);
}
.panel-3 {
  box-shadow: none;
}
.panel-4 {
  background-image: url(cat/cat-003.svg);
}
.panel-5 {
  background-image: url(cat/cat-004.svg);
}
.panel-6 {
  background-image: url(cat/cat-005.svg);
}
.panel-7 {
  box-shadow: none;
}
.panel-8 {
  background-image: url(cat/cat-007.svg);
}
.panel-9 {
  background-image: url(cat/cat-008.svg);
  box-shadow: none;
}
.panel-copyright {
  box-shadow: none;
  font-size: .75em;
}

/* media query 1 */
@media only screen and (min-width: 400px) {
  
  .grid-1 {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: auto 200px auto 200px 200px auto 200px auto;
  }  
  .panel-title,
  .panel-3,
  .panel-6,
  .panel-7,
  .panel-copyright {
    grid-column: span 2;
  }
  .panel-copyright {
    text-align: right;
  }
  .panel-7 {
    text-align: center;
  }
  h1 {
    font-size: 3em;
  }
  
}

/* media query 2 */
@media only screen and (min-width: 600px) {
  
  .grid-1 {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: auto 200px 200px 200px auto;
  }
  .panel-title,
  .panel-copyright {
    grid-column: span 3;
  }
  .panel-3,
  .panel-6 {
    grid-column: auto;
  }
  .panel-8 {
    grid-column: span 2;
  }
  h1 {
    font-size: 3.5em;
  }
  p {
    font-size: 1.3em;
  }
  
  /* flexbox centering */
  .panel-3 {  
    display: flex;
    align-items: center;
  }
  
  /* layering */
  .panel-7 {
    grid-column: 1;
    grid-row: 4;
    z-index: 1;
    margin: -5px 0 0 -10px;
    transform: rotate(-2deg);
  }
  
  .panel-7 p {
    background: #f8f7f2;
    box-shadow: 0 0px 0px 5px #251b19;
    text-align: left;
  }
  
  .panel-8 {
    grid-column: 1 / span 2;
    grid-row: 4;
    background-size: 70%;
    background-position: right;
  }
  
}

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

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

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

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

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

<title> Grid: сравнение с Flex</title>

<h5>Flex Box - ориентируется по одной оси (одномерный)</h5>
<div class="flex container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
</div>

<h5>CSS Grid - оринетируется по двум осям (двумерный)</h5>
<div class="grid container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
html { box-sizing: border-box; font-family: sans-serif; }
*, *::before, *::after { box-sizing: inherit; }

.container{ 
  /* border: 1px dashed #666; */
}
.item{ 
  background: #899db9; 
  padding: 1em;
  border: 1px solid #fff;
  display: flex; justify-content:center; align-items:center;
  color:rgba(0,0,0,.5);
}

.flex {
  display: flex;
  flex-wrap: wrap;
}

.flex .item:nth-child(-n + 3) { flex-basis: 33.33%; }
.flex .item:nth-child(n + 4) { flex-grow: 1; }

.grid {
  display: grid;
  grid: "a b c d d"
        "f f g d d";
}

.grid .item:nth-child(4) { grid-area: d; }
.grid .item:nth-child(5) { grid-area: f; }

Ссылки






Справочник CSS
×
Справочник CSS