+
+
diff --git a/recipes/masonry/index.md b/recipes/masonry/index.md
new file mode 100644
index 0000000000..230d1fcc26
--- /dev/null
+++ b/recipes/masonry/index.md
@@ -0,0 +1,178 @@
+---
+title: "Плиточная раскладка"
+description: "Как реализовать плиточную раскладку на чистом CSS во времена со слабой поддержкой grid-template-rows: masonry."
+authors:
+ - alextaraskina
+keywords:
+ - masonry
+ - masonry layout
+related:
+ - css/grid-guide
+ - css/flex
+ - css/child
+tags:
+ - article
+---
+
+## Задача
+
+Плиточная раскладка — это метод компоновки, при котором блоки по одной из осей вписываются в стандартную сетку (занимают определённое количество колонок или строк), а по другой оси располагаются так, чтобы не оставалось лишнего пространства, как бы прижимаются вплотную друг к другу.
+
+
+
+В 2020 году был опубликован черновик спецификации [CSS Grid Level 3](https://drafts.csswg.org/css-grid-3/). В этом документе описывается простой способ создания плиточной раскладки. Для реализации необходимо создать контейнер с блоками и задать одной из осей контейнера свойство [`grid-template-*`](/css/grid-template/) со значением `masonry`. Выглядит это следующим образом:
+
+```css
+.container {
+ display: grid;
+ grid-template-rows: masonry;
+ grid-template-columns: repeat(3, 1fr);
+}
+```
+
+В данный момент эта технология экспериментальная и пока доступна только в браузере [Firefox Nightly](https://www.mozilla.org/ru/firefox/channel/desktop/). Nightly — это нестабильная версия для активных пользователей, которые хотят участвовать в тестировании новых функций.
+
+Существует решение этой задачи на чистом CSS, но у него есть свои нюансы. Давайте разбираться.
+
+## Готовое решение
+
+Разметка — контейнер с блоками разной высоты:
+
+```html
+
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
+```
+
+Стили:
+
+```css
+.container {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: column;
+ gap: 8px 4px;
+ /* высота контейнера фиксированная */
+ /* должна быть больше любой из колонок */
+ height: 600px;
+ width: 100%;
+}
+
+.item {
+ width: calc(100% / 3);
+}
+
+.item:nth-child(3n + 1) { order: 1; }
+.item:nth-child(3n + 2) { order: 2; }
+.item:nth-child(3n) { order: 3; }
+
+.container::before,
+.container::after {
+ content: "";
+ flex-basis: 100%;
+ width: 0;
+ order: 2;
+}
+```
+
+## Разбор решения
+
+Создаём флекс-контейнер, внутрь кладём блоки разной высоты. Задаём свойство [`flex-wrap`](/css/flex-wrap/) со значением `wrap` — нам нужно, чтобы блоки располагались в несколько рядов. Теперь определим направление расположения блоков внутри контейнера. На этом моменте и появляются первые сложности.
+
+Если установить на контейнере свойство [`flex-direction`](/css/flex-direction/) со значением `row`, то блоки будут размещаться в строку. При этом высота строки будет равна высоте наибольшего блока. Таким образом, по вертикальной оси между соседними блоками будет оставаться пустое пространство.
+
+
+
+Если установить `flex-direction` со значением `column`, то нужно также указать фиксированную высоту контейнера (иначе блоки не будут переноситься в новую колонку). Для динамической подгрузки данных, когда количество блоков и необходимая высота контейнера неизвестны, такое решение не подойдёт. В этом случае стоит смотреть в сторону решения на JavaScript.
+
+Ещё один недостаток — нарушается удобный при чтении слева направо порядок элементов. Но это можно победить, переопределив порядок элементов.
+
+
+
+### Меняем порядок блоков
+
+Переопределим порядок блоков с помощью свойства [`order`](/css/order/). Блок с меньшим числовым значением встаёт перед блоком с бо̀льшим значением, вне зависимости от фактического расположения блоков в HTML-разметке.
+
+Сейчас, при чтении слева направо, пользователь видит блоки в следующем порядке:
+
+
+
+Первый элемент и каждый третий после него (`3n+1`) должны рендериться первыми. Устанавливаем для них `order: 1`. Затем должны идти элементы `3n+2`, и в последнюю очередь — элементы `3n`. Для выбора элементов по формуле воспользуемся псевдоклассом [`:nth-child`](/css/child/).
+
+```css
+.item:nth-child(3n+1) { order: 1; }
+.item:nth-child(3n+2) { order: 2; }
+.item:nth-child(3n) { order: 3; }
+```
+
+
+
+### Добавляем колонки-разделители
+
+Казалось бы, порядок элементов исправлен. Но такой подход сработает не всегда. Предположим, у нас есть колонка с невысокими блоками. Они вписываются по высоте в контейнер, и ещё остаётся значительное пространство под ними. В таком случае блок, который должен рендериться в следующей колонке, может не перенестись и попасть не в свою колонку.
+
+В примере ниже белым цветом обозначены блоки, которые не перенеслись в новую колонку, а вписались по размеру в предыдущую. Элемент 2 отрендерился в первой колонке, хотя должен быть во второй. Элемент 3 — во второй вместо третьей.
+
+
+
+Нам нужно как-то контролировать переносы элементов в новые колонки. Для решения этой задачи создадим дополнительные скрытые колонки-разделители. Разместим эти скрытые колонки между основными. Установим высоту в 100% — так, чтобы другие элементы не сливались со скрытой колонкой в одну.
+
+```css
+/* Создаём две скрытые колонки с помощью псевдоэлементов */
+.container::before,
+.container::after {
+ content: "";
+ flex-basis: 100%;
+ width: 0;
+ order: 2;
+}
+```
+
+
+
+Готово!
+
+## А что, если колонок больше трёх?
+
+Если колонок больше, нам нужно адаптировать решение, а именно:
+
+- поправить ширину колонок;
+- добавить дополнительные колонки-разделители и поправить их расположение.
+
+В случае с тремя колонками мы создавали две дополнительные скрытые колонки с помощью псевдоэлементов [`::before`](/css/before/) и [`::after`](/css/after/). При большем числе видимых колонок число скрытых также растёт, и псевдоэлементы уже не подходят. Используем обычный [`
`](/html/div/). К элементу добавляем два класса — `item` и `break`. Класс `item` используется как для видимых элементов, так и для скрытых. Класс `break` — только для скрытых.
+
+Разметка для скрытой колонки:
+
+```html
+
+```
+
+Стили:
+
+```css
+.break {
+ flex-basis: 100%;
+ width: 0;
+ margin: 0;
+}
+```
+
+Количество скрытых колонок-разделителей равно количеству колонок минус один. В разметке эти элементы должны располагаться после всех видимых элементов, в самом конце контейнера. Их фактическое расположение [определяется стилями](/recipes/masonry/#menyaem-poryadok-blokov).
+
+