Grid Layout (гриды) продолжение

Продолжаем узучать гриды.
Интервал
Существует три свойства CSS, связанные с интервалами:
row-gap - задает интервал между рядами (строками).
column-gap - задает интервал между столбцами (колонками).
gap - сокращенное свойство, позволяет добавлять равномерный интервал сразу между рядами и столбцами. Если указать один параметр, то интервал будет применен для обоих значений.

Размеры для всех свойств могут быть указаны как абсолютные (px, pt), так и относительные (%, em).

Синтаксис:
row-gap: размер; /* интервал между рядами */
column-gap: размер; /* интервал между столбцами (колонками) */

gap: размер размер; /* ряд столбец */
gap: размер /* равномерный отступ сразу между столбцами и колонками */
Это интересно!
Свойства column-gap и row-gap раньше назывались grid-column-gap и grid-row-gap, но сейчас выводятся из стандарта.
В спецификации CSS появляется все больше возможностей задавать такие же отступы в модуде Flexbox, чтобы уйти от текущих проблем с отрицательными отступами при создании макетов. По этой причине было принято решение сделать одни правила и для flex, и для grid.
Использование gap в сетке
Возьмем пример из прошлого урока и добавим в него интервалы в 20 px.
Когда мы добавим в нашу сетку gap, она будет работать так будто линии получили толщину.
<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>grid-template-areas</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="container">
      <header class="bg-header grid-header">grid-area: header;</header>
      <nav class="bg-nav grid-nav">grid-area: nav;</nav>
      <aside class=" bg-aside grid-aside">grid-area: aside;</aside>
      <main class=" bg-main grid-main">grid-area: main;</main>
      <footer class="bg-footer grid-footer">grid-area: footer;</footer>
     </div>
  </body>
</html>
/* Общие настройки */
body {
  padding: 5;
  margin: 20px;
  font-family: "Montserrat", sans-serif;
  font-size: 16px;
}

/* В контейнере задаем визуальный макет */ 
.container {
  display: grid;
  grid-template-columns: repeat(6, 100px); 
  grid-template-rows: repeat(4, 100px);
  grid-template-areas:
    "header header header header aside aside"
    "nav main main main aside aside"
    "nav main main main aside aside"
    "footer footer footer footer footer footer"; 
  gap: 20px; /* Добавляем интервалы */
}

/* Зададим элементу нужную область */
.grid-header {
  grid-area: header;
}

.grid-nav {
  grid-area: nav;
}

.grid-main {
  grid-area: main;
}

.grid-aside {
  grid-area: aside;
}

.grid-footer {
  grid-area: footer;
}
Если посмотреть на макет с помощью DevTools, то получим следующее:
Линии сетки стали толщиной 20 px и поэтому раздвигают сетки дальше друг от друга.
Но при этом дорожки все еще имеют одинаковый размер, который мы задали в grid-template-columns и rows.
Точно также работают свойства row-gap и column-gap.
Свойство gap и flexbox
Свойство gap можно использовать во Flexbox.
Для flexbox это свойство нужно было уже очень давно, так как оно отбрасывает необходимость margin.
Во flexbox для добавления пространства между элементами нужно каждому из них добавить свойство margin, иногда даже отрицательное значение, что может очень сильно путать.

Рассмотрим пример использования с margin, а затем с использованием gap.
<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>grid-template-areas</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="flex-container">
      <header class="flex-card">header</header>
      <nav class="flex-card">nav</nav>
      <aside class="flex-card">aside</aside>
      <main class="flex-card">main</main>
      <footer class="flex-card">footer</footer>
     </div>
  </body>
</html>
body {
  padding: 5%;
  margin: 0;
  font-family: "Montserrat", sans-serif;
  color: #0077b6;
  font-size: 24px;
}
    
.flex-container {
  display: flex;
  flex-flow: row wrap; /* по умолчению слева направо и разрешен перенос на новую строку */
}

.flex-card {
  border: 1px solid #0077b6;
  padding: 1rem;
  border-radius: 5px;
  flex: 1 1 16rem;
}

/* Задаем отступы с помощью margin */
.flex-container > .flex-card {
  margin-bottom: 50px;
  margin-left: 10px;
}
  
Теперь смотрите как легко и просто можно назначить интервал с помощью свойства gap. А получаем одно и тоже.
/* Задаем отступы с помощью gap */
.flex-container {
  display: flex;
  flex-flow: row wrap; /* по умолчению слева направо и разрешен перенос на новую строку */
  row-gap: 50px; /*интервал между строками */
  column-gap: 10px; /* интервал между столбцами */
}
Можно по прежнему использовать margin или padding, чтобы добавить визуальное пространство между элементами макета. Но gap имеет некоторые преимущества:
- Он определяется на уровне контейнера, что означает мы определяем интервалы один раз для всего макета. Использование margin тредует объявления для каждого элемента.
- Gap по умолчанию работает правильно с помощью одной строчки кода. Например, при попытке ввести пространство между flex-элементами, а не вокруг них, margin потребует особые указания для удаления дополнительных полей перед первым элементом и после него. C gap этого делать ненужно.

Например, имея margin: 0 20px на каждом flex-элементе, то в DevTools мы увидим:
С помощью gap на контейнере получится следующее:
Но margin и gap могут хорошо сочетаться вместе.
Свойство gap - это только одна часть пустого пространства, созданного между элементами в контейнере.
Margin и padding могут дополнительно увеличивать свободное пространство, которое уже определено свойством gap.

Рассмотрим на простом примере. У нас есть простой flex макет с шириной 900px, значением gap в 40px, распределением контента (justify-content), а также значениями margin 0 20px и padding 20px.
/* Задаем отступы с помощью gap, mardin и padding*/
.flex-container {
  width: 900px;
  display: flex;
  gap: 40px; 
  justify-content: space-around;
}

.flex-container > .flex-card {
  margin: 0 20px;
  padding: 20px;
}
Из получившегося результата мы видим несколько разных типов пустого пространства между flex-элементами:
- Gap определил начальное расстояние между элементами.
- Margin отодвинул элементы еще дальше друг от друга, но в отличие от gap добавлин пространство с обеих сторон всех элементов.
- Padding дал пространство внутри каждого элемента.
- Justify-content равномерно распределил все элементы внутри flexbox.
Позиционирование
В Grid Layout есть два свойства, позволяющие автоматически выровнять полосы внутри контейнера:
  • justify-content - выравнивает Grid-полосы по горизонтали, т.е. выравниваются колонки относительно контейнера.
    Свойство justify-content может принимать следующие значения:
    - stretch - значение по умолчанию, когда колонкам не выставлена фиксированная ширина.
    - start - это нормальное поведение элементов внутри контейнера. Все столбцы стартуют от левого края и идут по горизонтали друг за другом.
    - end - все элементы внутри контейнера сместятся к правой границе.
    - center - все элементы внутри контейнера будут отцентрованы внутри контейнера.
    - space-around - сделает равные отступы между колонками и половину этого расстояния по краям контейнера.
    - space-evenly - отступы по краям контейнера выставляются не в половину расстояния между элементами, а в полную ширину.
    - space-between - все элементы получают одинаковое расстояние между собой. При этом нет никаких отступов от краёв. Первый и последний элемент прижимаются к краям контейнера. Если таких элемента всего два, то они расположатся по краям контейнера.

  • align-content
    Свойство align-content по своему поведению очень похоже на свойство justify-content. Разница заключается только в направлении выравнивания. align-content выровняет ряды внутри контейнера.

Ничего не напоминает? Ранее вы изучали Flexbox и должны были узнать эти свойства. Теперь вы можете увидеть, как тесно между собой связаны модули Flexbox и CSS Grid Layout. Разрабатывая с использованием этих двух модулей, вы часто будете пользоваться одинаковыми свойствами, которые имеют и одинаковые значения. Посмотрим на них.

В качестве примера возьмём 3 полосы, каждую из которых покрасим в свой цвет. Сам контейнер покрасим в серый цвет, чтобы видеть его ширину. Сначала добавим по одному свойству Justify-content, затем рассмотрим пример с align-content.
<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>grid-template-areas</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="container">
      <header class="bg-header card-header"></header>
      <main class="bg-main card-main"></main>
      <footer class="bg-footer card-footer"></footer>
     </div>
  </body>
</html>
body {
    margin: 0;
    font-family: "Montserrat", sans-serif;
    color: #10002b;
    font-size: 24px;
  }
  
.bg-header {
  padding: 5px;
  background: #89C4F4;
}
  
.bg-main {
  padding: 5px;
  background: #4B77BE;
} 

.bg-footer {
  padding: 5px;
  background: #1F4788;
} 
  
.container {
  width: 100%;
  height: 100px;
  background: #ccc;
  display: grid;
  grid-template-columns: repeat(3, 100px);

  justify-content: start; 
}

  
body {
    margin: 0;
    font-family: "Montserrat", sans-serif;
    color: #10002b;
    font-size: 24px;
  }
  
.bg-header {
  padding: 5px;
  background: #89C4F4;
}
  
.bg-main {
  padding: 5px;
  background: #4B77BE;
} 

.bg-footer {
  padding: 5px;
  background: #1F4788;
} 
  
.container {
  width: 100%;
  height: 300px;
  background: #ccc;
  display: grid;
  grid-template-rows: repeat(3, 100px);

  align-content: start; 
}

  
Неявная сетка
мириририармирф
Создаем сетку нужного размера
Начнём с пустого шаблона. Чтобы было наглядно видно, как в сетке располагаются ячейки, сделаем так:
<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Пишем гриды</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <!-- создаём контейнер, который будет отвечать за нашу сетку -->
    <div class="container">
      <!-- и создаём 5 вложенных элементов -->
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
     </div>
  </body>
</html>
/*общие настройки сетки*/
.container {
  display: grid; /* подключаем сетку */
  border: 5px solid #138900; /*рисуем зелёные рамки*/
}
/*внешний вид ячеек*/
 .container > * {
   background-color: #cfe8dc;  /*фоновый цвет*/
   border-radius: 5px; /*скругление углов*/
   padding: 7px; /*отступ от содержимого до края ячейки*/
   margin: 1px;  /*расстояние от одной границы ячейки до другой*/
 }
Вот что получается, если у сетки не задавать никаких параметров:
  • элементы располагаются друг под другом в одну колонку;
  • сетка растягивается по ширине на весь экран;
  • элементы тоже растягиваются по ширине;
  • по высоте сетка занимает ровно столько, чтобы вместить всё содержимое. На всю высоту сетка автоматически не растягивается.
Формируем строки и колонки
Давайте посмотрим, как добавление строк и колонок в сетку влияет на положение и размер ячеек.

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

Внутри себя они могут принимать множество различных значений. Некоторые из них:
1. Любые выше описанные css-единицы.
2. min-content - ширина колонки будет равна минимально возможной.
3. max-content - ширина колонок будет равнв максимально возможной.
4. minmax(min, max) - функция, принимающая два значения: минимальный и максимальный размер, т.е. вы устанавливаете границы, в пределах которых браузер сам выбирает ширину.
5. auto - браузер автоматически подстраивает колонки по ширине.
6. <line-name> - переменная на ваш выбор, подробнее будет описано дальше;

Сделаем в сетке три колонки по 150 пикселей:
/*общие настройки сетки*/
.container {
  display: grid; 
  border: 5px solid #138900; 
  grid-template-columns: 150px 150px 150px; /*добавляем три колонки размерами 150 пикселей*/
}

/*внешний вид ячеек*/
 .container > * {
   background-color: #cfe8dc;  
   border-radius: 5px; 
   padding: 7px; 
   margin: 1px;  
 }
Сетка сразу уменьшилась по высоте, подстраиваясь под количество элементов. Теперь укажем высоту в 80px для элементов:
/*общие настройки сетки*/
.container {
  display: grid; 
  border: 5px solid #138900; 
  grid-template-columns: 150px 150px 150px; 
  grid-template-rows: 80px; /* Будет создан 1 ряд высотой 80px */
}

/*внешний вид ячеек*/
 .container > * {
   background-color: #cfe8dc;  
   border-radius: 5px; 
   padding: 7px; 
   margin: 1px;  
 }
Так как мы задали только один параметр в 80px, высота поменялась только у первой строки.
Сделаем 3 строки одинаковой высоты:
/*общие настройки сетки*/
.container {
  display: grid; 
  border: 5px solid #138900; 
  grid-template-columns: 150px 150px 150px; 
  grid-template-rows: 80px 80px 80px ; /* Будет создано 3 ряда высотой 80px*/
}

/*внешний вид ячеек*/
 .container > * {
   background-color: #cfe8dc;  
   border-radius: 5px; 
   padding: 7px; 
   margin: 1px;  
 }
Так как мы явно указали, что нам в сетке нужно 3 строки, то у нас появилась пустая третья строка. В ней пока никаких элементов, но сетка уже предусмотрела для них свободное место.

Чтобы не писать подряд несколько значений используйте команду:
grid-template-rows: repeat(3, 80px);

Это функция, которая принимает 2 значения:
1. Сколько раз повторить размер
2. Какое значение нужно повторить.

В нашем случае она повторяет нужный размер (80 пикселей) определённое количество раз — в нашем случае это 3 раза.

То же самое работает и с колонками — сделаем 4 одинаковые колонки используя функцию repeat ():
grid-template-columns: repeat(4, 150px);
Теперь сделаем так: добавим еще элементов, вторую строку растянем вниз до конца окна — используем для этого 1fr, а столбцы сделаем одинаковой ширины.
/*общие настройки сетки*/
.container {
  display: grid; 
  border: 5px solid #138900; 
  grid-template-columns: repeat(4, 1fr); 
  grid-template-rows: 80px 1fr 80px ;
}

/*внешний вид ячеек*/
 .container > * {
   background-color: #cfe8dc;  
   border-radius: 5px; 
   padding: 7px; 
   margin: 1px;  
 }
Кажется, что 1fr, который должен был растянуть вторую строку на всё свободное место, не работает. Но с ним всё в порядке, смотрите, что произошло:
  1. Первая строка получила ширину 80 пикселей.
  2. Третья строка тоже получила 80 пикселей.
  3. После этого браузер, глядя на 1fr, стал высчитывать, какую высоту сделать у второй строки.
  4. Браузер знает, что 1fr должен заполнить всё оставшееся свободное место в сетке, но у нас нижняя граница сетки прилегает вплотную к последней строке.
  5. Это значит, что свободного места в сетке нет, поэтому браузер учёл все внутренние отступы из общих настроек ячейки и сделал вторую строку минимальной высоты.

Чтобы это исправить, нужно явно задать общую высоту сетки:
/*общие настройки сетки*/
.container {
  display: grid; 
  border: 5px solid #138900; 
  grid-template-columns: repeat(4, 1fr); 
  grid-template-rows: 80px 1fr 80px;
  height: 350px; /*Задали высоту контейнера*/
}

/*внешний вид ячеек*/
 .container > * {
   background-color: #cfe8dc;  
   border-radius: 5px; 
   padding: 7px; 
   margin: 1px;  
 }
Чтобы сетка растянулась по высоте на всё окно, используют относительные единицы, например, vh — она указывает, сколько процентов от высоты окна будет занимать элемент. Чтобы растянуть сетку до края, напишем:
/*общие настройки сетки*/
.container {
  display: grid; 
  border: 5px solid #138900; 
  grid-template-columns: repeat(4, 1fr); 
  grid-template-rows: 80px 1fr 80px;
  height: 100vh; /*Задали высоту контейнера*/
}

/*внешний вид ячеек*/
 .container > * {
   background-color: #cfe8dc;  
   border-radius: 5px; 
   padding: 7px; 
   margin: 1px;  
 }
Расположение элементов в сетке
Ранее упоминалось о том, что линия сетки автоматически пронумерована.
У каждой линии сетки есть 2 значения: номер при счете слева направо и номер при счете справа налево, в этом случае они имеют отрицательное значение.

Номера можно использовать для привязки элементов к конкретным линиям сетки.
Для их расположения в сетке существует 4 свойства:
grid-column-start - начальная вертикальная линия элемента в сетке
grid-column-end - конечная вертикальная линия элемента в сетке. Значение указывает до какой колонки располагать элемент, т.е. сама колонка не включается. Если нужно включить и указанную колонку, то прибавьте единицу. Например, для 12 колоночного макета указывается значение 13.
grid-row-start - начальная горизонтальная линия
grid-row-end - конечная горизонтальная линия. Также указыкает до какой строки распологать элемет.

Используя данные свойства, можно задать не только начальные позиции, от которых отрисуется элемент, но и конечные, тем самым задав ширину элементу.
Создадим простой трехколоночный макет сайта. Скопируйте ниже код себе и попробуйте различные значения линий.
<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Пишем гриды</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <!-- создаём контейнер, который будет отвечать за нашу сетку -->
    <div class="container">
      <header class="bg-header grid-header"> Шапка сайта</header>
      <aside class=" bg-aside grid-aside">Сайдбар</aside>
      <main class=" bg-main grid-main">Основной контент</main>
     </div>
  </body>
</html>
/* основная настройка*/
body {
  padding: 5;
  margin: 0px; /*убираем верхнее и нижнее поле, равное 1em*/
  font-family: "Montserrat", sans-serif;
  font-size: 18px;
}

/* делаем оформление*/
.bg-header {
  padding: 15px;
  background: #E7ECEF;
}

.bg-aside {
  padding: 15px;
  background: #6096BA;
}

.bg-main {
  padding: 15px;
  background: #A3CEF1;
}

/* задаем гриды и количество колонок и строк*/
.container {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(12, 1fr);
  height: 99vh;
}

/*задаем гибкую настройку хедеру*/
.grid-header {
  grid-column-start: 1;
  grid-column-end: 13;
  grid-row-start: 1;
  grid-row-end: 3;
}

/*задаем гибкую настройку сайдбару*/
.grid-aside {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 3;
  grid-row-end: 13;
}

/*задаем гибкую настройку основному контенту*/
.grid-main {
  grid-column-start: 4;
  grid-column-end: 13;
  grid-row-start: 3;
  grid-row-end: 13;
}
Обратите внимание на то, что для шапки указано значение grid-column-start. Если убрать это значение, что элемент начнет растягиваться не слева направо, а справа налево.
/*задаем гибкую настройку хедеру*/
.grid-header {
  grid-column-start: 4; /* Поменяли значение с 1 на 4*/
  grid-column-end: 13;
  grid-row-start: 1;
  grid-row-end: 3;
}
Для этих свойств есть сокращенные версии записи.
grid-column - сокращенная запись горизонтальной линии для задания начала и конца значения
grid-row - сокращенная запись вертикальной линии для задания начала и конца значения

Синтаксис:
/* Полная версия записи для строк(рядов) */
grid-row-start: 2; /* Элемент начинается со 2 линии рядов */
grid-row-end: 4; /* Элемент заканчивается на 4 линии рядов */

/*Сокращенная версия*/
grid-row: 2 / 4; /* скачала указывается начальное значение, затем через знак деления конечное*/

/* Полная версия записи для колонок(столбцов)*/
grid-column-start: 1;
grid-column-end: 3;

/*Сокращенная версия*/
grid-column: 1 / 3; /* скачала указывается начальное значение, затем через знак деления конечное*/
Используя сокращенные записи пример выше можно написать так:
/*Можно написать с помощью сокращенных свойств*/
.grid-header {
  grid-column: 1/13;
  grid-row: 1/3;
}

.grid-aside {
  grid-column: 1/4;
  grid-row: 3/13;
  
}

.grid-main {
  grid-column: 4/13;
  grid-row: 3/13;
}
Также упоминались отрицательные значения. В этом случае отсчет начинается с конца столбца и ряда. Это полезно при растягивании элемента на всю ширину контейнера. Вместо подсчета линий, в качестве конечного значения можно указать -1, что автоматически растянет элемент на до конечной линии.

Для наглядности, возьмем наш макет и шапку сайта растянем теперь при помощи отрицательного конечного значения.
Мы также без вреда макету можем заменить значения у строк(рядов) сайдбара, с 13 на -1 и строки с колонками основного контента, 13 поменяем на -1.
/*Сокращенная запись*/
.grid-header {
  grid-column: 1/-1; /*Поменяли 13 на -1. Отсчет с конца*/
  grid-row: 1/3;
}

.grid-aside {
  grid-column: 1/4;
  grid-row: 3/-1; /*Поменяли 13 на -1. Отсчет с конца*/
  
}

.grid-main {
  grid-column: 4/-1; /*Поменяли 13 на -1. Отсчет с конца*/
  grid-row: 3/-1; /*Поменяли 13 на -1. Отсчет с конца*/
}



/*Второй вариант полной записи*/
.grid-header {
  grid-column-start: 1;
  grid-column-end: -1; /*Поменяли 13 на -1. Отсчет с конца*/
  grid-row-start: 1;
  grid-row-end: 3;
}

.grid-aside {
  grid-column-start: 1;
  grid-column-end: 4;
  grid-row-start: 3;
  grid-row-end: -1; /*Поменяли 13 на -1. Отсчет с конца*/
}

.grid-main {
  grid-column-start: 4;
  grid-column-end: -1; /*Поменяли 13 на -1. Отсчет с конца*/
  grid-row-start: 3;
  grid-row-end: -1; /*Поменяли 13 на -1. Отсчет с конца*/
}
Существует еще один вариант задания разметки внутри контейрена.
Иногда, при верстке макета неудобно знать, с какой линии элемент начинается и где заканчивается - многое нужно держать в голове. Удобнее знать начальную полосу и количество колонок, которые он должен занять - для этого используется ключевое слово span. Он указывает элементу сколько ячеек ему нужно занять внутри контейнера.

Синтаксис:
grid-column: 1/ span 4; /* Указывает, что элемент занимает 4 колонки по горизонтали */
grid-row: 1/ span 2; /* Указывает, что элемент занимает 2 строки по вертикали*/
Давайте добавим в макет меню навигации и поменяем линии на ячейки без вреда макету.
Скопируйте код себе и также попробуйте поиграть с значениями.
<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Пишем гриды</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <!-- создаём контейнер, который будет отвечать за нашу сетку -->
    <div class="container">
      <nav class="bg-nav grid-nav">Меню</nav>
      <header class="bg-header grid-header"> Шапка сайта</header>
      <aside class=" bg-aside grid-aside">Сайдбар</aside>
      <main class=" bg-main grid-main">Основной контент</main>
     </div>
  </body>
</html>
body {
  padding: 5;
  margin: 0px; /*убираем верхнее и нижнее поле, равное 1em*/
  font-family: "Montserrat", sans-serif;
  font-size: 18px;
}

.bg-header {
  padding: 15px;
  background: #E7ECEF;
}

.bg-nav {
  padding: 15px;
  background: #8b8c89;
}

.bg-aside {
  padding: 15px;
  background: #6096BA;
}

.bg-main {
  padding: 15px;
  background: #A3CEF1;
}

.container {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(12, 1fr);
  height: 99vh;
}

.grid-header {
  grid-column: 1/-1;
  grid-row: 1/ span 2; /*Указали, что элемент занимает 2 ячейки по вертикали вместо grid-row: 1/3; */
}

.grid-nav {
  grid-column: 1/ span 2;  /*Указали, что элемент занимает 2 ячейки по горизонтали вместо grid-column: 1/ 3;*/
  grid-row: 3/-1;
}

.grid-aside {
  grid-column: span 2; /* Использование только ключевого слова. Браузер разместить элемент с тем количеством строк и колонок, которое указано. В нашем случае 2 колонки.*/
  grid-row: 3/-1;
  
}

.grid-main {
  grid-column: 3/ span 8; /* Указали, что элемент занимает 8 ячеек по горизонтали */
  grid-row: 3/-1;
}
Именование линий грида
Чтобы быстро описать простую сетку с помощью гридов, нужно хорошенько поорудовать свойствами grid-row-start/grid-row-end и grid-column-start/grid-column-end. Что мы описали выше. Но получается несколько многословно.

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

При именовании линий их имена заключаются в квадратные скобки, а затем через пробел указывается ширина столбца или высота строки.
grid-template-columns: [название линии] размер [название линии] размер;
grid-template-rows: [название линии] размер [название линии] размер;

Например:
grid-template-columns: [header-top] 1fr repeat(3, 1 fr);
/* [header-top] 1fr - создаст именованую линию header-top и полосу шириной в 1 фракцию, затем
repeat(3, 1 fr) создаст 3 полосы шириной в 1 фракцию */

Или для удобства можно начать с новой линии:
grid-template-columns:
   [header-start] 1fr /* Обратите внимание, что знак ; не ставится до тех пор пока не закончите перечисление*/
   [header-end] 10px
   [nav-start] 1fr 
   [nav-end] 10px
   [main-start] 1fr 
   [main-end] -1;

grid-template-rows: 
   [aside-start] 1fr 
   [aside-end] 10px 
   [content-start] 1fr;
Можно подставлять любое количество названий и в уже сверстанный макет. Запись не повредит шаблону.

Затем, используя эти названия, мы можем позиционировать элементы между определенными линиями:
.special-item {
  grid-column: header-start / nav-end;
  grid-row: aside-start;
  background-color: #bbb;
}
Давайте в нашем макете зададим имя только начальным линиям.
.container {
  display: grid;
  grid-template-columns:
    [nav-start] repeat(2, 1fr) /*Левая линия от которой начинает отрисовываться меню */
    [main-start] repeat(8, 1fr) /* Линия от которой начинается основной контент. Также ограничивает ширину nav (меню) */
    [aside-start] repeat(2, 1fr); /* Линия от которой начинается сайдбар */
  grid-template-rows: 
    [header-start] 1fr 1fr /* Самая верхняя линия от которой отрисуется шапка сайта */
    [content-start] repeat(9, 1fr); /* Линия, откуда начинается основной контент сайта - nav, main, aside. Нужна для ограничения высоты шапки */
  height: 99vh;
}

.grid-header {
  grid-column: 1/-1;
  grid-row-start: header-start; /* Начинается шапка сайта с header-start */
  grid-row-end: content-start; /* Шапка заканчивается на контенте, тем самым мы ограничили размеры хедера в 2 фракции */
}

.grid-nav {
  grid-column-start: nav-start; /* Начало меню */
  grid-column-end: main-start; /* Ограничили меню основным контентом */
  grid-row: 3/-1;
}

.grid-aside {
  grid-column-start: aside-start; /* Начало сайдбара */
  grid-column-end: -1;
  grid-row: 3/-1;
}

.grid-main {
  grid-column-start: main-start; /* Начало основного контента */
  grid-column-end: 11;
  grid-row: 3/-1;
}
Важно!
Создание именовыных линий не отнимает у них индекса. К линиям все еще можно обращаться по индексу (как по положительному, так и отрицательному)
Именование областей грида
До этого мы рассматривали только именованные линии, однако существует другой способ. Мы можем именовать грид-области и размещать элементы в них.
Для создания именованной области используется свойство grid-template-areas.
В этом свойстве задаются имена ячейкам, а затем элементы привязываются к этим именам через свойство grid-area: указывается для отдельного элемента.

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

Синтаксис визуально показывает как выглядит сетка:
grid-template-areas: 
   "имя  имя2  имя3"
   "имя  имя2 имя3"
   "имя  none   .";

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

"имя имя2 имя3" - в значении внутри кавычек нужно через пробелы указывать имена. Каждые кавычки с именами будут представлять собой ряд сетки, а имена внутри кавычек задают колонки.

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

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

none — область не определена
Важно!
Область должна быть прямоугольной формы.
Каждый ряд должен иметь одинаковое количество ячеек.
А дальше для каждого элемента прописывается своё название в grid-area. Одному элементу в HTML может соответствовать только одна грид-область.
grid-template-areas: 
   "имя  имя2  имя3"
   "имя  имя2 имя3"
   "имя  none   .";

/* Указываем элементу область */
.grid-element-1 {
  grid-area: имя;
}

.grid-element-2 {
  grid-area: имя2;
}

.grid-element-3 {
  grid-area: имя3;
}
Давайте рассмотрим макет грида 6 колонок на 4 строки:
<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>grid-template-areas</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="container">
      <header class="bg-header grid-header">grid-area: header;</header>
      <nav class="bg-nav grid-nav">grid-area: nav;</nav>
      <aside class=" bg-aside grid-aside">grid-area: aside;</aside>
      <main class=" bg-main grid-main">grid-area: main;</main>
      <footer class="bg-footer grid-footer">grid-area: footer;</footer>
     </div>
  </body>
</html>
/* Общие настройки */
body {
  padding: 5;
  margin: 20px;
  font-family: "Montserrat", sans-serif;
  font-size: 16px;
}

/* Фон блоков */
.bg-header {
  padding: 5px;
  background: #E7ECEF;
}

.bg-nav {
  padding: 5px;
  background: #8b8c89;
}

.bg-aside {
  padding: 5px;
  background: #6096BA;
}

.bg-main {
  padding: 5px;
  background: #A3CEF1;
}

.bg-footer {
  padding: 5px;
  background: #E7ECEF;
}

/* В контейнере задаем визуальный макет */ 
.container {
  display: grid;
  grid-template-columns: repeat(6, 100px); /* говорим, что будет 6 колонок размером 100 пикселей */
  grid-template-rows: repeat(4, 100px); /* говорим, что будет 4 строки размером 100 пикселей */
  grid-template-areas: /* Задаем именование областей */
    "header header header header aside aside" /* хедер будет занимать 4 колонки, а сайдбар - 2 */
    "nav main main main aside aside" /* nav займет 1 колонку, main - 3, сайдбар - 2 */
    "nav main main main aside aside" /* nav займет 1 колонку, main - 3, сайдбар - 2 */
    "footer footer footer footer footer footer"; /* footer займет 6 колонок */
}

/* Зададим элементу нужную область */
.grid-header {
  grid-area: header;
}

.grid-nav {
  grid-area: nav;
}

.grid-main {
  grid-area: main;
}

.grid-aside {
  grid-area: aside;
}

.grid-footer {
  grid-area: footer;
}
grid-template-areas и пустые ячейки грида
Иногда может понадобиться нестандартный макет, но из-за того, что количество колонок должно быть одинаковым в каждой строке, удалить одну из областей не получится, поэтому можно использовать свойство grid-template-areas и пометить некоторые ячейки как пустые.

Для этого вместо буквенного именования области используется символ точки "."

Давайте сделаем макет 3х3 и зададим ему три цвета.
<!DOCTYPE html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>grid-template-areas пропуск ячейки</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="container">
      <div class="dark-blue grid-dark"></div>
      <div class="blue grid-blue"></div>
      <div class="light-blue grid-light"></div>
     </div>
  </body>
</html>
body {
  padding: 5;
  margin: 20px;
  font-family: "Montserrat", sans-serif;
  font-size: 16px;
}

.dark-blue {
  padding: 5px;
  background: #023e8a;
}

.blue {
  padding: 5px;
  background: #0077b6;
}

.light-blue {
  padding: 5px;
  background: #6096BA;
}

.container {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  grid-template-areas:
    "dark-blue blue light-blue"
    "dark-blue blue light-blue"
    "dark-blue blue light-blue";
}

.grid-dark {
  grid-area: dark-blue;
}

.grid-blue {
  grid-area: blue;
}

.grid-light {
  grid-area: light-blue;
}
Если мы хотим, чтобы во втором ряду осталась только центральная ячейка, то заменим blue в первом и последнем ряду на точки:
.container {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  grid-template-areas:
    "dark-blue . light-blue"
    "dark-blue blue light-blue"
    "dark-blue . light-blue";
}
Полезные ссылки
Интерактивная игра на отработку гридов - https://cssgridgarden.com/#ru
Шпаргалка по гридам - https://tpverstak.ru/grid/
Еще одна шпаргалка по гридам (английский) - https://css-tricks.com/snippets/css/complete-guide-grid/
Практика
1. Испытание - клавиатура

Создайте клавиатуру по макету.

Подсказка:
  • По умолчанию, каждая клавиша занимает 2 колонки внутри сетки
  • Текст внутри клавиш должен быть отцентрован
  • Расстояние между клавишами: 5px
  • Мнемоники помогут в вёрстке кнопок

В основной контейнер добавь:
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
1. Второй макет
Сделай макет, состоящий из:
- шапки
- левого сайдбара
- правого сайдбара
- основного контента
- футера

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