Grid в CSS
CSS Grid Layout — это новое многообещающее явление в мире верстки. Используя Grid, можно построить макеты, которые ранее невозможно было построить в CSS. С ним возможности чуть ли не безграничны. Grid претендует на звание «лучшей системы для вёрстки макетов HTML». В этой статье я попробую разобраться какой он, этот Grid, на вкус и доступно поделиться знаниями с вами.
Grid поддерживается почти всеми браузерами, поэтому изучать уже пора!
Читайте также: Flexbox в CSS
Базовые знания
Grid — это сетка с элементами на ней. Расставлять элементы можно как угодно. Представьте себе шахматную доску и фигуры, Grid контейнер это доска, элементы это фигуры. А дальше ставь как нравится.
Grid — это набор горизонтальных и вертикальных «линий», которые пересекаются между собой и создают сетку из рядов и колонок. Элементы могут быть помещены в сетку, опираясь на номер линии или номер ряда/колонки.
Чтобы разобраться с Грид-сеткой нужно понять из чего конкретно состоит эта сетка. Для этого хорошенько изучите схему ниже и описание к ней.

Описание Грид сетки
-
Контейнер — содержит Grid сетку, в которой находятся элементы.
-
Элементы — HTML элементы внутри сетки. Ими станут HTML элементы первого уровня (прямые дети контейнера). Чтобы элемент появился в сетке, в нем (внутри) элемента должно быть хоть что-то (текст, другие HTML теги). Пустой элемент - это всего лишь ячейка для расположения в нем чего-либо.
-
Линии — это образные линии (на самом деле никаких линий нет), разделяющие сетку на колонки и ряды, они создают структуру сетки. Линии автоматически нумеруются. Также линиям можно указывать имена, чтобы потом прикреплять к ним элементы по номеру или по имени линии. По сути линия — это номер или имя колонки/ряда. Расстояние между линиями (колонками/рядами) можно указать через grid-gap:, grid-row-gap:, grid-column-gap:.
-
Ряд/колонка (row/column, track) — все что находится между соседними линиями, т.е. линии разделяют сетку на ряды и колонки.
-
Ячейка (cell) — место куда будет расположен элемент. Ячейка это пересечение колонки и ряда.
-
Область (area, поле) — объединение одной или нескольких ячеек в общую ячейку (поле). Это такая большая ячейка также ограниченная линиями. Области можно задать имя, чтобы удобно было помещать туда элементы.
- Разрыв (gap) — расстояние между рядами и колонками. Разрывает линию на две. Так между линиями, а как следствие и колонками/рядами, ячейками появляется пустое место. Это своего рода margin, border-spacing между ячейками. По умолчанию линия между ячейками всего одна (ячейки слеплены), но если указать разрыв, то мы разорвем линию, и появится расстояние между колонками/рядами, при этом номер или имя линии (колонки/ряда) остается одно.
Для включения Grid, любому HTML элементу достаточно присвоить css свойство display:grid;
или display:inline-grid;
.
.grid { display: grid; } .inline-grid { display: inline-grid; }
<div class="grid"> <div>display: grid</div> </div> Текст, в котором есть <div class="inline-grid"> <div>display: inline-grid</div> </div> продолжение текста

После включения grid свойства, внутри контейнера создаются grid сетка, а все вложенные элементы (первого уровня) станут ячейками сетки.
.grid { display: grid; }
<div class="grid"> <div>1</div> <div>2</div> </div>

Пример создания грид-блока с двумя колками и тремя рядами разных размеров:
.grid{ display: grid; grid: 1fr 25% 30px / 40% 1fr; /* ряды / колонки */ grid-gap: 1em; height: 200px; }
<div class="grid"> <div class="item">item 1</div> <div class="item">item 2</div> <div class="item">item 3</div> <div class="item">item 4</div> <div class="item">item 5</div> <div class="item">item 6</div> </div>

Особенности Grid
Элементы Grid сетки можно расставлять сразу на несколько полей сетки. Можно менять направление или расположения элементов в сетке. Колонкам и рядам можно давать имена. Можно создавать шаблон сетки и расставлять элементы по шаблону.
-
Размеры колонок/рядов. Сетку можно создавать с точными или гибкими размерами колонок/рядов (шириной/высотой). Точные это px, em, %, а гибкие новая единица измерения в grid fr (фракция - свободное место в сетке).
-
Расположение элемента. Элементы можно размещать в указанном месте сетки, указав номер колонки/ряда или их имя (если оно есть). Или путем привязки элемента к области Grid (область нужно создать). Если не указать конкретное расположение элемента в сетке, то элемент размещается по умолчанию в первую свободную ячейку: как во flex: по горизонтали (→) или по вертикали (↓). Поведение по умолчанию можно изменить через свойство grid-auto-flow:.
-
Выравнивание элементов. Элементы внутри ячейки можно выравнивать по горизонтали/вертикали. Выравнивается вложенный в ячейку элемент, а не сама ячейка. Например, в контейнере есть вложенный элемент первого уровня (это ячейка), внутри него есть «текст» или какой-то «div» (текст или div - это реальный элемент) выравнивание элемента выровняет вложенный в ячейку элемент внутри ячейки (размеры ячейки при этом не изменятся).
-
Несколько элементов в одной ячейке. В одной ячейке или области можно разместить несколько элементов. Чтобы указать кто «выше» (важнее) и кто «ниже» (неважный), нужно использовать css свойство z-index:.
- Расширение сетки. Сколько колонок/рядов имеет сетка обычно указывается сразу, но если разместить элемент за пределами сетки (указать ему номер ряда/ячейки, который выходит за пределы сетки), тогда сетка автоматически расширяется и создаются дополнительные линии (колонки/ряды).
CSS свойства Grid
Для контейнера
- display:
Включает grid свойство для элемента. Под это свойство попадает сам элемент и вложенные в него элементы: затрагиваются только потомки первого уровня - они станут элементами grid контейнера.
- grid - элемент растягивается на всю ширину и имеет свое полное пространство среди окружающих блоков. Происходит перенос строк в начале и в конце блока.
- inline-grid — элемент обтекается другими элементами. При этом его внутренняя часть форматируется как блочный элемент, а сам элемент — как встроенный.
grid и inline-grid отличаются тем что по-разному взаимодействуют с окружающими элементами, подобно display:block и display:inline-block.
- grid-template-rows:
- grid-template-columns:
Указывают из скольки рядов (строк) и скольки колонок состоит сетка и какие у них размеры. Т.е. указывается сразу два понятия: сколько и какой размер.
В значении через пробелы указываются размеры: высота ряда (rows) или ширина колонки (columns). Сколько раз будет указан размер, столько будет рядов/колонок.
// синтаксис: grid-template-rows: размер размер ...; grid-template-columns: размер размер ...; grid-template-rows: [line-name] размер [line-name] размер ... [last-name]; grid-template-columns: [line-name] размер [line-name] размер ... [last-name];
-
размер — это высота ряда или ширина колонки, может быть:
-
auto — размер ряда/колонки подстраивается под размеры элементов, так, чтобы уместился самый большой из них. Не дает сжиматься меньше min-width или min-height самого широкого или высокого элемента соответственно. Не дает растягиваться больше, чем max-content. Если в контейнере есть свободное место, то размер может растянуться до конца контейнера.
-
px, em, %, vh, vw — размер абсолютный (px, pt), относительный (em, vw, vh) или в
%
от ширины/высоты контейнера. -
fr (фракция - свободное место в сетке) — специальная единица измерения в grid. Свободное место в контейнере делится на фракции, так если одной колонке указать 1fr, а другой 2fr, то вторая будет больше первой в 2 раза и обе они заполнят все свободное пространство. Аналог flex-grow: у флексов. Тут можно также указывать дробные значения: 0.5fr, 2.3fr.
-
min-content — наименьший размер контента. Для текста это ширина самого длинного слова или неразрывного фрагмента.
-
max-content — наибольший размер контента. Для текста это длина самой большой строки без переносов.
-
fit-content( max ) — функция которой передается макс. размер. Если контент меньше этого размера, ведет себя как auto, если больше, то ограничивает размер ряда/колонки до указанного в параметре max.
- minmax( min, max ) — функция, позволяет разом указать минимальный и максимальный размер.
-
-
line-name (имя линии) — перед размером можно указать (создать) имя для линии (ряда/колонки). Имя указывается в квадратных скобках
[имя] 100px
. Также можно указать сразу несколько имен через пробел внутри квадратных скобок:[имя еще_имя] 100px
. Символы в имени можно использовать любые, в том числе кириллицу. - last-name (последнее имя) — указанное имя станет именем начальной линии ряда/колонки, но ряд/колонка состоит из двух линий (они ведь имеют размер). Так имя линии является именем начала одной колонки (ряда) и именем конца предыдущей колонки (ряда). И так вот заполняется сетка, но в конце остается ряд/колонка и указанное для неё имя это имя только начальной линии этого ряда/колонки, а у конечной линии имени нет. Такое имя последней линии можно указать в конце. Т.е. получается так:
[имя] 100px [имя2] 100px [последнее-имя]
.
У двух этих свойств есть сокращенные записи:
Примеры значений:
// grid-template-columns: может принимать все те же значения grid-template-rows: none; grid-template-rows: auto auto; grid-template-rows: 100px 1fr; grid-template-rows: [linename] 100px; grid-template-rows: [linename1] 100px [linename2 linename3]; grid-template-rows: minmax(100px, 1fr); grid-template-rows: fit-content(40%); grid-template-rows: repeat(3, 200px); grid-template-rows: 200px repeat(auto-fill, 100px) 300px; grid-template-rows: minmax(100px, max-content) repeat(auto-fill, 200px) 20%; grid-template-rows: [linename1] 100px [linename2] repeat(auto-fit, [linename3 linename4] 300px) 100px; grid-template-rows: [linename1 linename2] 100px repeat(auto-fit, [linename1] 300px) [linename3]; // глобальные grid-template-rows: inherit; grid-template-rows: initial; grid-template-rows: unset;
Примеры:
Создадим сетку (контейнер) с тремя колонками и тремя рядами последняя колонка и ряд будут иметь одинаковое имя 'main'
.grid { grid-template-columns: 100px 10% [main] 800px; grid-template-rows: 100px 10% [main] 800px; }
Если не указать имя, то ряд/колонка автоматом получает два порядковых числовых имени: положительное и отрицательное:
grid-template-columns: 40px 50px auto 50px 40px; grid-template-rows: 25% 100px auto;
Укажем конкретные имена (обратите внимание как указывается имя для последней линии):
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end]; grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
Меню может иметь не одно, а несколько имен, этот пример добавляет два имени row1-end и row2-start:
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
Если в перечисление размеров колонок есть повторяющиеся части, то можно использовать функцию repeat():
grid-template-columns: repeat(3, 20px [col-start]) 5%; // в результате получим: grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
Если несколько строк имеют одно и то же имя, на них можно ссылаться по имени и порядковому числу:
.item { grid-column-start: col-start 2; }
fr
позволяет указать размер относительный оставшегося свободного места в контейнере. В этом примере свободное место в контейнере делится на число указанных фракций (у нас 3) и для каждой определяется ширина. Так если ширина контейнера 90px то каждая колонка будет шириной по 30px.grid-template-columns: 1fr 1fr 1fr;
Свободное пространство высчитывается после того как посчитаны жесткие размеры (включая разрывы). В этом примере размер свободно пространства высчитывается как ширина контейнера минус 50px.
grid-template-columns: 1fr 50px 1fr 1fr;
-
- grid-template-areas:
Позволяет создать визуальный шаблон сетки. В этом свойстве задаются имена ячейкам, а затем элементы привязываются к этим именам через свойство grid-area: указываемое для отдельного элемента.
Синтаксис шикарен, потому что визуально показывает как выглядит сетка:
grid-template-areas: "имя имя2 имя3" "имя имя4 имя5" "имя none ."; // или можно так grid-template-areas: "имя имя2 имя3" "имя имя4 имя5" "имя6 none ."; // или одинарные кавычки grid-template-areas: 'имя имя2 имя3' 'имя имя4 имя5' 'имя6 none .';
-
"имя имя2 имя3"
— в значении внутри кавычек нужно через пробелы указывать имена. Каждые кавычки с именами будут представлять собой ряд сетки, а имена внутри кавычек задают имена ячейкам внутри этого ряда. -
"имя имя имя2"
— если указать одно и тоже имя несколько раз подряд, то имя объединит ячейки и мы получим область (большую ячейку). Объединять ячейки таким способом можно не только внутри ряда, но и между рядами. -
.
(точка) — указывается вместо имени и обозначает ячейку которую нужно пропустить (пустую ячейку). Можно использовать несколько точек подряд, пока между ними нет пробела они будут считаться за одну. none
— область не определена
Заметки:
- Символы в имени можно использовать любые, в том числе кириллицу.
-
Каждый ряд должен иметь одинаковое количество ячеек.
-
При использовании этого метода линии (включая последнюю линию) получают имена автоматически. Например, если область называется
bar
, то имя начальной линии ряда и колонки у этой области будетbar-start
, а имя последнейbar-end
. Это значит, что некоторые линии будут иметь много имен. Например крайняя левая линия из примера ниже (шаблон страницы) будет иметь сразу три имени:header-start
,main-start
иfooter-start
.Такая же логика работает и наоборот, если линиям указать имена
дом-start
идом-end
, то все что находится межу этими линиями превращается в область (ячейку) с именемдом
.
grid-template-areas: также можно указывать в первом значении свойств:
Примеры:
Шаблон страницы. Создадим сетку с четырьмя колонками и тремя рядами. Весь верхний ряд будет шапкой (header), средний ряд будет контентом (main) и сайдбаром (sidebar), между которыми оставим место (.). И последний рад будет подвалом (footer).
.item-a { grid-area: header; } .item-b { grid-area: main; } .item-c { grid-area: sidebar; } .item-d { grid-area: footer; } .container { grid-template-columns: 50px 50px 50px 50px; grid-template-rows: auto; grid-template-areas: "header header header header" "main main . sidebar" "footer footer footer footer"; }
Размеры и области можно указывать одновременно:
.grid { display: grid; grid-template-rows: [header-top] minmax( 6em, auto) [header-bottom main-top] 1fr [main-bottom]; grid-template-columns: 1fr 30%; grid-template-areas: "header header" "main menu"; } .header { grid-area: header; } .main { grid-area: main; } .menu { /* прикрепление к области (ячейке) */ grid-area: menu; /* такое же прикрепление, но к именам линий ряда */ grid-row: main-top / main-bottom; /* или */ grid-row: menu-start / menu-end; /* или */ grid-row: 2 / 3; }
-
- grid-template:
Позволяет разом указать три свойства: grid-template-rows, grid-template-columns и grid-template-areas.
// синтаксис: grid-template: none; grid-template: grid-template-rows / grid-template-columns; grid-template: [ line-names? "строка" размер? line-names? ] ... grid-template: [ line-names? "строка" размер? line-names? ] ... / [ line-names? размер ] ... line-names? // то что в [] или до ? — можно не указывать // ... — можно повторять
Это свойство можно заменить на сокращенное grid: grid-template-rows / grid-template-columns
Примеры:
В первом параметре (в рядах) можно указать шаблон (области). 25px - это высота ряда.
grid-template: "header header header" 25px "footer footer footer" 25px / auto 50px auto;
Также можно указывать имена для линий ряда:
grid-template: [header-top] "a a a" [header-bottom] [main-top] "b b b" 1fr [main-bottom] / auto 1fr auto; // в результате получится вот это: grid-template-areas: "a a a" "b b b"; grid-template-rows: [header-top] auto [header-bottom main-top] 1fr [main-bottom]; grid-template-columns: auto 1fr auto;
grid-template: не сбрасывает свойства для рядов/колонок по умолчанию: grid-auto-columns:, grid-auto-rows:, grid-auto-flow:. Чтобы это сделать, лучше вместо grid-template: использовать свойство grid:.
- repeat() — функция
Позволяет повторять что-либо N раз. Используется при создании колонок/рядов в свойствах: grid-template-rows:, grid-template-columns:, grid-template:.
repeat( сколько_раз, что_повторять )
Варианты использования repeat():
-
Повторение любого числа рядов/колонок указанное число раз.
repeat( 2, 50px ) // 50px 50px repeat( 2, 50px 70px ) // 50px 70px 50px 70px
-
Повторение одного ряда/колонки до заполнения контейнера. Количество повторов при этом задается через:
- auto-fill — повторяет ряд/колонку пока есть место в контейнере. Хотя бы одно повторение будет всегда.
- если контейнер ограничен максимальным размером, ряд/колонка повторяется пока есть место вставить очередной ряд/колонку.
- если у контейнера задан минимальный размер, ряд/колонка повторяется пока не превысят этот минимум.
- auto-fit — то же самое, но после размещения элементов оставшиеся пустыми ряд/колонка сжимаются и исчезают, в результате контейнер всегда будет выглядеть заполненным (без пустых мест на краях) (это видно визуально только если в контейнере есть резиновый блок).
- auto-fill — повторяет ряд/колонку пока есть место в контейнере. Хотя бы одно повторение будет всегда.
Ограничения по repeat():
- Нельзя вкладывать repeat() в repeat().
-
С auto-fill и auto-fit можно повторять только не резиновые размеры (имеющие конечную ширину/высоту). Т.е. нет смысла использовать min-content, max-content, fr, auto - все они резиновые и в результате мы получим только один ряд/колонку без каких-либо повторений.
repeat( auto-fill, 100px ) // можно repeat( auto-fit, minmax(100px, 1fr) ) // можно repeat( auto-fill, auto ) // нельзя repeat( auto-fit, 1fr ) // нельзя
-
repeat() c
auto-fill
илиauto-fit
может быть только один на одно свойство (grid-template-rows: или grid-template-columns:).// можно grid-template-columns: repeat(3, 50px 5%) repeat(auto-fill, 100px) repeat(4, 80px) // нельзя (2 repeat с неизвестным количеством повторений) grid-template-columns: repeat(auto-fill, 50px) repeat(2, 100px) repeat(auto-fit, 80px)
- Если есть repeat() c
auto-fill
илиauto-fit
, то в остальных repeat для этого же свойства нельзя повторять неточные размеры: *-content, fr или auto.// можно (в первом repeat повторяется конкретная ширина в процентах) grid-template-columns: repeat(4, 10%) repeat(auto-fill, 10em) // нельзя (в одном repeat есть auto-fill, а в другом repeat повторяется заранее неизвестная ширина). grid-template-columns: repeat(auto-fill, 100px) repeat(4, 1fr)
Примеры:
-
- minmax() — функция
Позволяет задавать минимальное и максимальное значения для ряда/колонки. Используется в свойствах, где нужно задавать размер: grid-template-rows:, grid-template-columns:, grid-template:.
minmax( мин_значение, макс_значение )
Значение может быть:
- px, em, rem, ... — единицы длины (100px)
- % — проценты (10%)
-
fr — гибкие размеры. Может использоваться только для макс. значения.
-
max-content — наименьший возможный размер ячейки, при котором содержимое свободно в ней умещается. Например, если в ячейке текст, идеальной шириной ячейки будет вся длина текста (в одну строку без переносов).
-
min-content — наименьший размер, при котором ячейка не переполняется. Например, если в ячейке текст то ширина будет равна самому длинному слову в тексте.
-
auto — зависит от того, используется оно как максимальное или минимальное значение в функции minmax():
- если в качестве максимума, то тоже самое что max-content.
- если в качестве минимума, то значение будет минимальным возможным размером для ячейки. Такой размер отличается от min-content и задается свойствами min-width или min-height.
Примеры:
Варианты использования:
grid-template-columns: minmax( 100px, 200px ) 1fr 1fr; grid-template-columns: minmax( 200px, 50% ) 1fr 1fr; grid-template-columns: minmax( 200px, 1fr ) 1fr 1fr; grid-template-columns: minmax( min-content, max-content ) 1fr 1fr; grid-template-columns: minmax( auto, auto ) 1fr 1fr; grid-template-columns: repeat( auto-fit, minmax(200px, 1fr) );
Если указанное максимальное значение окажется меньше минимального, оно игнорируется и работает только мин. значение.
Подробное описание примеров смотрите в статье: как работает minmax().
- grid-row-gap:
- grid-column-gap:
- grid-gap:
grid-row-gap: задает разрыв между рядами.
grid-column-gap: задает разрыв между колонками.
grid-gap: задает разрыв для рядов и колонок разом. Это сокращение для двух предыдущих свойств. Если указать один параметр он будет выставлен для обоих значений.// синтаксис: grid-row-gap: размер; grid-column-gap: размер; grid-gap: размер размер; /* row column */ grid-gap: размер;
Размер может быть абсолютным (px, pt), относительным (%, em).
Примеры:
grid-column-gap: 10px; grid-row-gap: 15px;
Заметка: префикс
grid-
будет удален и названия свойств станут: column-gap: и row-gap:. Chrome 68+, Safari 11.2 и Opera 54+ уже поддерживают свойства без этого префикса.- align-content:
- justify-content:
- place-content:
Выравнивает ряды/колонки. Выравниваются ячейки сетки, не элементы внутри ячеек. Чтобы выровнять элементы, используйте: justify-items, align-items, place-items.
// синтаксис: align-content: значение; // выравнивает ряды по вертикали ↓↑ justify-content: значение; // выравнивает колонки по горизонтали ←→ place-content: значение; // сокращенная запись: установит оба значения place-content: align-content justify-content; // сокращенная запись
Значение может быть:
- stretch (default) — растягивает ряды/колонки (ячейки) полностью. Все пространство контейнера заполняется. Имеет смысл только если у рядов/колонок размер не задан жестко (они резиновые). Если они не резиновые, то работает как start.
- start — ряды/колонки упакованы вплотную друг к другу к начальному краю контейнера.
- end — ряды/колонки упакованы вплотную друг к другу к конечному краю контейнера.
-
center — ряды/колонки упакованы вплотную друг к другу и находятся по середине контейнера.
- space-around — свободное пространство равномерно распределяется между рядами/колонками и добавляется по краям. Получается, что крайние ряд/колонка не прижимаются к краям контейнера, но расстояние до края в два раза меньше, чем между рядами/колонками.
- space-evenly — тоже что и space-around, только расстояние до краев контейнера такое же как и между рядами/колонками.
- space-between — крайние ряд/колонка прижимаются к краям контейнера и свободное место равномерно распределяется между рядами/колонками.
Редкие значения:
-
safe значение — если ширина колонки или высота ряда превышает размер контейнера, то значение переключается на start. В значении тут может быть только: center или end.
-
unsafe значение — значение остается указанным, даже если ширина колонки или высота ряда превышает размер контейнера. В значении тут может быть только: center или end.
safe unsafe выравнивание
Примеры:
Полный синтаксис:
Выше для упрощения был не полный синтаксис, однако он покрывает 99% нужного.
// синтаксис: align-content: normal | <distribution> | <overflow>? <position> | <baseline> justify-content: normal | <distribution> | <overflow>? [ <position> | left | right ] // <distribution> = space-between | space-around | space-evenly | stretch // <overflow> = unsafe | safe // <position> = center | start | end | flex-start | flex-end // <baseline> = [ first | last ]? baseline // то что в [] или до ? — можно не указывать
- left — для justify-content, не работает для align-content. Колонки упакованы вплотную друг к другу к левому краю контейнера.
-
right — для justify-content, не работает для align-content. Колонки упакованы вплотную друг к другу к правому краю контейнера.
-
flex-start — тоже что start для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как start.
-
flex-end — тоже что end для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как end.
- baseline, first baseline, last baseline — выравнивает по линии текста (первой или последней). Обратная совместимость: для first baseline это start, для last baseline это end.
Все варианты значений:
align-content:
// базовое выравнивание align-content: center; align-content: start; align-content: end; align-content: flex-start; align-content: flex-end; align-content: normal; // выравнивание по линии текста align-content: baseline; align-content: first baseline; align-content: last baseline; // распределение align-content: space-between; align-content: space-around; align-content: space-evenly; align-content: stretch; // когда элемент перекрывает контейнер align-content: safe center; align-content: unsafe center; // глобально align-content: inherit; align-content: initial; align-content: unset;
justify-content:
// базовое выравнивание justify-content: center; justify-content: start; justify-content: end; justify-content: flex-start; justify-content: flex-end; justify-content: left; justify-content: right; align-content: normal; // выравнивание по линии текста не имеет смысла // распределение justify-content: space-between; justify-content: space-around; justify-content: space-evenly; justify-content: stretch; // когда элемент перекрывает контейнер justify-content: safe center; justify-content: unsafe center; // глобально justify-content: inherit; justify-content: initial; justify-content: unset;
place-content:
/* базовое выравнивание */ /* align-content не может быть left или right */ place-content: center start; place-content: start center; place-content: end left; place-content: flex-start center; place-content: flex-end center; /* выравнивание по линии текста */ /* для второго параметра (justify-content) не имеет смысла */ place-content: baseline center; place-content: first baseline space-evenly; place-content: last baseline right; /* распределение */ place-content: space-between space-evenly; place-content: space-around space-evenly; place-content: space-evenly stretch; place-content: stretch space-evenly; /* глобально */ place-content: inherit; place-content: initial; place-content: unset;
- align-items:
- justify-items:
- place-items:
Выравнивает элементы сетки - то что находится внутри ячеек сетки. Срабатывает для всех элементов grid. Чтобы выровнять сами ячейки (ряды колонки), используйте: justify-content, align-content, place-content.
// синтаксис: align-items: значение; // выравнивает элементы по вертикали ↓↑ justify-items: значение; // выравнивает элементы по горизонтали ←→ place-items: значение; // сокращенная запись: установит оба значения place-items: align-items justify-items; // сокращенная запись
Значение может быть:
-
auto (default) — указывает использовать значение justify-items:, которое задается для контейнера. Если элемент позиционирован через absolute, то применяется normal.
- stretch — растягивает все элементы на всю ширину/высоту ячеек.
- start — размещает все элементы в начале ячеек (слева или сверху).
- end — размещает все элементы в конце ячеек (справа или внизу).
- center — размещает все элементы по центру ячеек.
Редкие значения:
-
safe значение — если ширина или высота элемента превышает размер ячейки, то значение переключается на start. В значении тут может быть только: center или end.
-
unsafe значение — значение остается указанным, даже если ширина или высота элемента превышает размер ячейки. В значении тут может быть только: center или end.
safe unsafe выравнивание
Примеры:
Полный синтаксис:
Выше для упрощения был не полный синтаксис, однако он покрывает 99% нужного.
// синтаксис: align-items: normal | stretch | [ <overflow>? <position> ] | <baseline> justify-items: normal | stretch | <overflow>? [ <position> | left | right ] | <baseline> | legacy [ left | right | center ] // <baseline> = [ first | last ]? baseline // <overflow> = unsafe | safe // <position> = center | start | end | self-start | self-end | flex-start | flex-end // то что в [] или до ? — можно не указывать
- left — для justify-items, не работает для align-items. Все элементы прижимаются к левому краю ячеек.
-
right — для justify-items, не работает для align-items. Все элементы прижимаются к правому краю ячеек.
-
flex-start — тоже что start для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как start.
-
flex-end — тоже что end для грид-сетки. Т.е. если элементы не являются детьми flex контейнера ведет себя как end.
-
baseline, first baseline, last baseline — выравнивает по линии текста (первой или последней). Обратная совместимость: для first baseline это start, для last baseline это end.
- legacy — позволяет управлять тем, как будет наследоваться значение детьми.
Если legacy указано без left, right, center, то значение просто наследуется у родителя или равно normal.
Когда justify-self:auto ссылается на значение justify-items:, берется значение без слова legacy, например у legacy left будет взято left. Это нужно для правильного выравнивания тега <center> или элемента с атрибутом align.
Все варианты значений:
align-items:
// базовые значения align-items: normal; align-items: stretch; // выравнивание позиции // align-items не может быть left или right align-items: center; align-items: start; align-items: end; align-items: flex-start; align-items: flex-end; align-items: self-start; align-items: self-end; // выравнивание по линии текста align-items: baseline; align-items: first baseline; align-items: last baseline; // когда элемент перекрывает контейнер align-items: safe center; align-items: unsafe center; // глобально align-items: inherit; align-items: initial; align-items: unset;
justify-items:
// базовые значения justify-items: auto; justify-items: normal; justify-items: stretch; // выравнивание позиции justify-items: center; justify-items: start; justify-items: end; justify-items: flex-start; justify-items: flex-end; justify-items: self-start; justify-items: self-end; justify-items: left; justify-items: right; // выравнивание по линии текста justify-items: baseline; justify-items: first baseline; justify-items: last baseline; // когда элемент перекрывает контейнер justify-items: safe center; justify-items: unsafe center; // выравнивание с приоритетом заимствования значения у родителя justify-items: legacy right; justify-items: legacy left; justify-items: legacy center; // глобально justify-items: inherit; justify-items: initial; justify-items: unset;
place-items:
// базовые значения place-items: auto center; place-items: normal start; // выравнивание позиции place-items: center normal; place-items: start auto; place-items: end normal; place-items: self-start auto; place-items: self-end normal; place-items: flex-start auto; place-items: flex-end normal; place-items: left auto; place-items: right normal; // выравнивание по линии текста place-items: baseline normal; place-items: first baseline auto; place-items: last baseline normal; place-items: stretch auto; // глобально place-items: inherit; place-items: initial; place-items: unset;
-
- grid-auto-rows:
- grid-auto-columns:
Устанавливает размер для авто-создаваемых (неявных) рядов/колонок.
Колонки/ряды создаются автоматически, когда в сетке элементов больше чем помещается в определенные ряды/колонки (ячейки) или когда элемент размещается за пределы указанной сетки.
// синтаксис: grid-auto-columns: размер; grid-auto-rows: размер;
Возможные значения размеров смотрите в описании grid-template-rows: и grid-template-columns: — может быть px, em, %, fr и т.д.
Примеры:
Чтобы понять как создаются авто-ячейки сетки, давайте представим что у нас есть сетка 2x2 - 2 ряда и 2 колонки:
grid-template-columns: 60px 60px; grid-template-rows: 90px 90px
Теперь, попробуем разместить элементы в сетку указав им позиции через свойства:
.item-a { grid-column: 1; grid-row: 2; } .item-b { grid-column: 5; grid-row: 2; }
Элемент .item-b мы попросили разместиться в несуществующей колонке 5. У нас только 2 колонки, поэтому сетка автоматически расшириться и ей будут добавлены еще 3 колонки с auto шириной. Текущие свойства позволяют нам задать размеры для таких неявных колонок:
grid-auto-columns: 60px;
Интересный момент для неявных колонок рядов и repeat():
- grid-auto-flow:
Определяет логику добавления элементов в пустые ячейки.
Когда элементам конкретно не указано в какой ячейке (области) они должны быть расположены, то они размещаются в пустые ячейки. По умолчанию заполнение идет слева направо (→) до конца ряда, переход на следующий ряд и опять заполнение (похоже на то как мы читаем текст).
По умолчанию алгоритм
row
т.е. такой → ↓ →, можно сделать так ↓ → ↓.// синтаксис: grid-auto-flow: row | column | row dense | column dense
-
row (default) — расставляет элементы в сетке по рядам → ↓ →. Добавляет ряды если в сетке нет места.
-
column — расставляет элементы в сетке по колонкам ↓ → ↓. Добавляет колонки если в сетке нет места.
- dense — включает «dense» алгоритм заполнения, который пытается разместить элементы так, чтобы не оставалось пустых пространств (по умолчанию работает алгоритм «sparse»). При этом элементы могут располагаться не по-порядку. При вставке каждого следующего элемента, алгоритм проверяет нет ли пустой ячейки сзади куда может поместиться текущий элемент, если есть, помещает его туда а не в следующую ячейку. dense имеет смысл только при наличии областей в сетке - это когда элементу указано разместиться сразу в несколько ячеек (через span), тогда он как правило не помещается в одну ячейку и остается пустое место.
Примеры:
Допустим у нас есть такой HTML:
<div class="grid"> <div class="item-a">item-a</div> <div class="item-b">item-b</div> <div class="item-c">item-c</div> <div class="item-d">item-d</div> <div class="item-e">item-e</div> </div>
Теперь, мы создали сетку с 5-ю колонками и двумя рядами и два элемента расположили в конкретные ячейки:
.grid { display: grid; grid-template: 60px 60px 60px 60px 60px / 30px 30px; /* по умолчанию: grid-auto-flow: row; */ }
Теперь установим
grid-auto-flow: column
:-
- grid:
Позволяет сокращенно записать свойства:
- grid-template-rows:
- grid-template-columns:
- grid-template-areas:
- grid-auto-rows:
- grid-auto-columns:
- grid-auto-flow:
Т.е. в этом свойстве можно описать почти все свойства грид-сетки. Однако, тут можно описать свойства только для «явных» или «неявных» рядов/колонок, сразу для тех и других не получиться. Если нужно указать свойства для тех и других, то нужно дописывать соответствующие свойства в дополнении к grid:.
// синтаксис: grid: none grid: grid-template grid: grid-template-rows / grid-template-columns grid: grid-template-areas grid: grid-template-rows / [auto-flow dense?] grid-auto-columns? grid: [auto-flow dense?] grid-auto-rows? / grid-template-columns // то что в [] или до ? — можно не указывать
-
none — устанавливает все свойства в начальное состояние.
-
grid-template-rows / [auto-flow +dense?] grid-auto-columns? — ключевое слово
auto-flow
с правой стороны слэша устанавливает grid-auto-flow: column.dense
включает алгоритм упаковки «dense». Если не указанgrid-auto-columns
, то он будет равен auto. - [auto-flow +dense?] grid-auto-rows? / grid-template-columns — ключевое слово
auto-flow
с левой стороны слэша устанавливает grid-auto-flow: row.dense
включает алгоритм упаковки «dense». Если не указанgrid-auto-rows
, то он будет равен auto.
Примеры:
grid: 'header header header header' 'main main main right right' 'footer footer footer footer'; // тоже что: grid-template-areas: 'header header header header' 'main main main right right' 'footer footer footer footer';
grid: 100px 300px / 3fr 1fr; // тоже что: grid-auto-flow: row; grid-template-columns: 200px 1fr;
grid: auto-flow dense 100px / 1fr 2fr; // тоже что: grid-auto-flow: row dense; grid-auto-rows: 100px; grid-template-columns: 1fr 2fr;
grid: 100px 300px / auto-flow 200px; // тоже что: grid-template-rows: 100px 300px; grid-auto-flow: column; grid-auto-columns: 200px;
Также можно указать более сложный, но удобный для настройки все и сразу:
grid: [row1-start] "header header header" 1fr [row1-end] [row2-start] "footer footer footer" 25px [row2-end] / auto 50px auto; // тоже что: grid-template-areas: "header header header" "footer footer footer"; grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end]; grid-template-columns: auto 50px auto;
И еще варианты:
grid: repeat(auto-fill, 5em) / auto-flow 1fr; grid: auto-flow 1fr / repeat(auto-fill, 5em); grid: auto 1fr auto / repeat(5, 1fr); grid: repeat(3, auto) / repeat(4, auto);
Для элементов
CSS свойства: float, display:inline-block, display:table-cell, vertical-align и column-* никак не влияют на элементы grid контейнера. У grid сетки свои правила...
- grid-row-start:
- grid-row-end:
- grid-column-start:
- grid-column-end:
- grid-row:
- grid-column:
Указывает положение элемента в сетке. Т.е. размещает элемент в указанную ячейку. Указывать нужно имя или номер линии к которой относится ячейка и к которой нужно прикрепить элемент.
grid-column
иgrid-row
— это сокращение для свойств:grid-column-start/grid-column-end
иgrid-row-start / grid-row-end
. Можно указать только первое (одно) значение, оно будет относиться к начальной линии и элемент будет растягиваться на 1 ряд/колонку (т.е. будет помещен в одну ячейку начальная линия которой указана).// синтаксис: grid-row-start: значение; // где начинается линия ряда grid-row-end: значение; // где кончается линия ряда grid-column-start: значение; // где начинается линия колонки grid-column-end: значение; // где кончается линия колонки grid-row: grid-row-start / grid-row-end; grid-column: grid-column-start / grid-column-end; // можно указать одно значение, второе значение будет span 1 grid-row: grid-row-start; grid-column: grid-column-start;
Значение может быть:
-
число/имя — порядковый номер или имя линии к которой нужно прикрепить текущий элемент.
-
span число — слово span значит растянуть. Текущий элемент будет растягиваться на указанное число рядов/колонок. Если указано слово span, то относится всегда ко второму значению.
-
span имя — слово span значит растянуть. Текущий элемент будет растягиваться до указанного названия линии ряда/колонки. Если указано слово span, то относится всегда ко второму значению.
- auto — элемент размещается по указанному алгоритму в свойстве контейнера grid-auto-flow:.
Примеры:
.item-a { grid-column-start: 2; grid-column-end: five; grid-row-start: row1-start grid-row-end: 3 }
.item-b { grid-column-start: 1; grid-column-end: span col4-start; grid-row-start: 2 grid-row-end: span 2 }
Если не установлены свойства grid-column-end/grid-row-end элемент по умолчанию будет растягиваться на 1 ряд/колонку.
Элементы могут перекрывать друг друга, в таких случаях приоритет можно выставить через z-index:.
Пример сокращенного указания линий.
grid-column: 3 / span 2; grid-row: third-line / 4;
-
- grid-area:
Дает элементу имя. По имени элемент будет относится к области указанной в свойстве grid-template-areas:. Или в значении можно указать номер/имя линий.
// синтаксис: grid-area: имя области; grid-area: row-start / column-start / row-end / column-end;
- имя области — название области сетки.
- row-start / column-start / row-end / column-end — может быть числом или именем линии.
Примеры:
grid-area: header; // или так: grid-area: 1 / col4-start / last-line / 6
- align-self:
- justify-self:
- place-self:
Выравнивает текущий элемент внутри ячейки. Применяется к отдельному элементу контейнера.
// синтаксис: align-self: значение; // выравнивает элемент внутри ячейки по вертикали ↓↑ justify-self: значение; // выравнивает элемент внутри ячейки по горизонтали ←→ place-self: значение; // сокращенная запись: установит оба значения place-self: align-self justify-self; // сокращенная запись
Значение может быть:
- stretch (defailt) — растягивает текущий элемент на всю ширину/высоту ячейки.
- start — размещает текущий элемент в начале ячейки (слева или сверху).
- end — размещает текущий элемент в конце ячейки (справа или внизу).
- center — размещает текущий элемент по центру ячейки.
Редкие значения:
-
safe значение — если ширина или высота элемента превышает размер ячейки, то значение переключается на start. В значении тут может быть только: center или end.
- unsafe значение — значение остается указанным, даже если ширина или высота элемента превышает размер ячейки. В значении тут может быть только: center или end.
Примеры:
Чтобы выровнять все элементы контейнера сразу, используйте: align-items:, justify-items:, place-items:. Там же вы найдете описание для редко-используемых значений.
Примеры
# Каркас HTML страницы
body { display: grid; grid: "header header header" 80px "nav section aside" 1fr "footer footer footer" 50px / 15% 1fr 18%; min-height: 100vh; } header { grid-area: header; } nav { grid-area: nav; } section { grid-area: section; } aside { grid-area: aside; } footer { grid-area: footer; }
<body> <header>header</header> <nav>nav</nav> <section>section</section> <aside>aside</aside> <footer>footer</footer> </body>
# Каркас для игрового приложения

#grid { /** * Две колонки: * 1. подстраивается под контент, * 2. получает все оставшееся пространтсов * (но не может быть меньше минимального размера контента в ней или controls блока в этой же колонке) * * Три ряда: * 1. подстраивается под контент, * 2. получает все свободное пространство * (но не может быть меньше минимального размера любого из блоков в этмо ряду) * 3. подстраивается под контент. */ display: grid; grid-template-columns: /* 1 */ auto /* 2 */ 1fr; grid-template-rows: /* 1 */ auto /* 2 */ 1fr /* 3 */ auto; /* растянем на всю высоту */ height: 100vh; } /* указывает позиции блоков в сетке с помощью координат */ #title { grid-column: 1; grid-row: 1; } #score { grid-column: 1; grid-row: 3; } #stats { grid-column: 1; grid-row: 2; } #board { grid-column: 2; grid-row: 1 / span 2; } #controls { grid-column: 2; grid-row: 3; justify-self: center; }
<div id="grid"> <div id="title">Game Title</div> <div id="score">Score</div> <div id="stats">Stats</div> <div id="board">Board</div> <div id="controls">Controls</div> </div>
Усложним задачу.
Теперь нам нужно сделать так чтобы при повороте мобильного устройства, каркас менялся и получалось так:

В этом случае удобнее будет использовать области Grid сетки.
/* книжная ориентация */ @media (orientation: portrait) { #grid { display: grid; /* создадаим структуру сетки и укажем названия областей, * Такая структура будет работать по умолчанию и подоходиь для альбомной ориентации. */ grid-template-areas: "title stats" "score stats" "board board" "ctrls ctrls"; /* укажем размеры для рядов и колонок. */ grid-template-columns: auto 1fr; grid-template-rows: auto auto 1fr auto; height: 100vh; } } /* альбомная ориентация */ @media (orientation: landscape) { #grid { display: grid; /* создадаим структуру сетки и укажем названия областей, * Такая структура будет работать по умолчанию и подоходиь для альбомной ориентации. */ grid-template-areas: "title board" "stats board" "score ctrls"; /* укажем размеры для рядов и колонок. */ grid-template-columns: auto 1fr; grid-template-rows: auto 1fr auto; height: 100vh; } } /* расположим элементы в именованные областя сетки */ #title { grid-area: title; } #score { grid-area: score; } #stats { grid-area: stats; } #board { grid-area: board; } #controls { grid-area: ctrls; justify-self: center; }
<div id="grid"> <div id="title">Game Title</div> <div id="score">Score</div> <div id="stats">Stats</div> <div id="board">Board</div> <div id="controls">Controls</div> </div>
Этот пример нужно просмотреть с телефона...
# Простой блок на Grid
# Масонри на Грид
Совсем без JS никак еще пока.
Сравнение Flex и Grid
В отличие от Flex, которая ориентирована на одну ось, Grid оптимизирована для двумерных компоновок: когда требуется расположить (выровнять) содержимое в обоих измерениях (по вертикали и горизонтали).
Кроме того, благодаря возможности явного позиционирования элементов в сетке, Grid позволяет выполнять кардинальные преобразования в структуре, не требуя никаких изменений HTML разметки. Комбинируя медиа-запросы со свойствами CSS, управляющими компоновкой контейнера grid и его дочерних элементов, можно адаптировать верстку под любые форм-факторы устройств.
Grid и Flexbox, имеют свои особенности и нельзя сказать, что одно заменяет другое. Скорее Флекс является дополнением к Грид, или наоборот.
Flexbox фокусируется на распределении пространства внутри одной оси, использует более простой подход к компоновке, может использовать систему упаковки строк на основе размера содержимого для управления своей вторичной осью и полагается на иерархию разметки. Тогда как Grid больше подходит для создания каркасов, потому что имеет более мощный и комплексный подход и в целом не зависит от иерархии разметки. В отдельных случаях Grid позволяет создать адаптивный макет, который невозможно создать с помощью Flex или как-то еще.
Поддержка браузерами
Grid поддерживается {percent} браузерами, которые используются сегодня.
Чтобы проверить в css поддерживает ли текущий браузер Grid, можно использовать @supports
(в IE не работает):
@supports( display: grid ) { /* grid поддерживается браузером */ div { display: grid; } } @supports not( display: grid ) { /* grid НЕ поддерживается браузером */ div { display: flex; } }
Видео по Grid
Ссылки
Полезные ссылки по Grid:
-
Гриды на грядках — игра позволяет с интересом попрактиковаться с гридами.
- grid.layoutit.com — интерактивный генератор грид сетки.
Использовал при написании:
-
Гид по гридам (css-tricks.com) (англ.)
-
Большая статься про гриды (css-live.ru)
-
CSS Grid (developer.mozilla.org)
- CSS Grid Layout. Быстрый старт (habrahabr.ru)