
Будущее плиточных веб-макетов уже настало! После того, как Mozilla заложила фундамент, потребовались годы работы команды Apple WebKit и множество этапов обсуждений в CSS Working Group с разработчиками всех браузеров, чтобы стало понятно, как всё это должно работать.
Представляем вашему вниманию CSS Grid Lanes.
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}Попробовать их можно уже сегодня в Safari Technology Preview 234.
Как работают Grid Lanes
Давайте подробно разберём, как создать вот такой классический макет.

Во-первых, HTML.
<main class="container">
<figure><img src="photo-1.jpg"></figure>
<figure><img src="photo-2.jpg"></figure>
<figure><img src="photo-3.jpg"></figure>
<!-- etc -->
</main>Для начала применим display: grid-lanes к элементу main для создания контейнера Grid, готового к изготовлению подобного макета. Затем мы используем grid-template-columns для создания полос со всеми возможностями CSS Grid.
В этом случае мы будем применять repeat(auto-fill, minmax(250px, 1fr)) для создания гибких столбцов шириной не менее 250 пикселей. Браузер сам будет решать, сколько столбцов нужно создать, заполняя всё имеющееся пространство.
Далее gap: 16px создаёт промежутки между полосами в 16 пикселей и промежутки между элементами полос тоже шириной 16 пикселей.
.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}Вот и всё! Всего в трёх строках CSS, совершенно без медиа-запросов и container queries, мы создали гибкий макет, который будет хорошо выглядеть во всех размерах экранов.
Можно представить его в виде шоссе, на котором машины едут плотно друг к другу.

Как и в классической библиотеке Masonry, когда браузер решает, куда поместить каждый элемент, следующий будет размещаться в том столбце, в котором он будет ближе к верхней части окна. Как и на шоссе, каждая машина «меняет полосу движения», чтобы оказаться в той полосе, которая позволит ей продвинуться вперёд дальше всего.
Этот макет позволяет пользователям переключаться по Tab между уже видимым контентом (не до конца первого столбца ниже видимой части экран, а затем обратно к верхней части второго столбца). Кроме того, благодаря такому макету можно создать сайт, бесконечно подгружающий новый контент в процессе скроллинга, без необходимости обработки макета с помощью JavaScript.
Сила Grid
Переменные размеры полос
Так как Grid Lanes используют всю мощь CSS Grid для задания полос при помощи grid-template-*, можно очень легко создавать изобретательные вариации дизайна.
Например, можно создать гибкий макет с попеременно идущими узкими и широкими столбцами, в котором первый и последний столбец всегда узкие, даже когда количество столбцов меняется с изменением размера вьюпорта. Это можно реализовать при помощи grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr).

Благодаря использованию синтаксиса grid-template-* возможности становятся практически безграничными.
Span элементов
Так как мы можем использовать всю мощь структуры Grid, то, разумеется, можно и применять в полосах span.

main {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(20ch, 1fr));
gap: 2lh;
}
article {
grid-column: span 1;
}
@media (1250px < width) {
article:nth-child(1) {
grid-column: span 4;
}
article:nth-child(2), article:nth-child(3), article:nth-child(4), article:nth-child(5), article:nth-child(6), article:nth-child(7), article:nth-child(8) {
grid-column: span 2;
}
}Для всех тизеров статей сначала задаётся span в один столбец. Затем конкретно первому элементу задаётся span на четыре столбца, а элементам со второго по восьмой — span на два столбца. Это создаёт гораздо более динамичный графический дизайн, чем типичный макет, преимущественно использовавшийся в течение последнего десятилетия, где всё имеет одинаковую ширину и высоту.
Размещение элементов
Также при помощи Grid Lanes можно размещать элементы явным образом. В примере ниже заголовок всегда находится в последнем столбце, вне зависимости от количества столбцов.

main {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(24ch, 1fr));
}
header {
grid-column: -3 / -1;
}Смена направления
Да, полосы могут идти в обоих направлениях! Во всех приведённых выше примерах создан «водопад», в котором контент выстраивается в столбцы. Но Grid Lanes можно использовать и для создания макета в другом направлении, в виде «кирпичной кладки».

Браузер автоматически создаёт «водопадный» макет, если определить столбцы при помощи grid-template-columns:
.container {
display: grid-lanes;
grid-template-columns: 1fr 1fr 1fr 1fr;
}Если вам нужно создать «кирпичную кладку», то задайте строки при помощи grid-template-rows:
.container {
display: grid-lanes;
grid-template-rows: 1fr 1fr 1fr;
}Благодаря новому значению по умолчанию normal для grid-auto-flow, это работает автоматически. Браузер определяет, создавать ему столбцы или строки, на основании того, чем вы задали полосы: grid-template-columns или grid-template-rows.
CSS Working Group пока продолжает обсуждение того, какое свойство должно в явном виде управлять направлением потока и каким должен быть его синтаксис. Группа размышляет над тем, следует ли использовать grid-auto-flow или создать новые свойства, например, grid-lanes-direction. Если вам любопытно изучить рассматриваемые варианты или поделиться своими мыслями, то прочитайте дискуссию.
Однако поскольку normal всё равно будет исходным значением, необязательно ждать этого решения, чтобы приступить к освоению Grid Lanes. Если вы определите только одно направление — grid-template-rows или grid-template-columns — то всё будет без проблем работать. (Но если что-то пойдёт не так, то проверьте, не задано ли для grid-auto-flow конфликтующее значение. При необходимости его можно сбросить при помощи unset.)
Чувствительность к размещению
Для Grid Lanes создана новая концепция «допуска» (tolerance). Она позволяет настраивать степень требовательности алгоритма при выборе размещения элементов.
Взгляните на иллюстрацию. Обратите внимание, что машина 4 немного короче машины 1. Если «допуск» равен нулю, то машина 6 окажется в самой правой полосе, а машина 7 — слева. Машина 6 окажется за машиной 4 справа, потому что так она продвинется чуть вперёд по «дороге» (ближе к верхней границе контейнера Grid). Тогда машина 7 займёт следующий ближайший к вершине слот и окажется за машиной 1 слева. Что мы получаем в итоге? Первая группировка контента по горизонтали упорядочена как 1, 2, 3, 4, а вторая — как 7, 5, 6.

Однако разница в длине между машинами 1 и 4 очень мала. Машина 6 несущественно ближе к верхней части страницы. И то, что элемент 6 находится справа, а элемент 7 — слева, вероятно, окажется неожиданным, особенно для пользователей, перемещающихся между контентом при помощи Tab, или если порядок контента каким-либо образом указан.
На практике такие крошечные различия в размерах неважны. Браузер должен считать размеры элементов наподобие машин 1 и 4 равными. Именно поэтому по умолчанию item-tolerance имеет значение 1em, то есть при выборе расположения следующего элемента будут учитываться различия в длине контента больше 1 em.
Если вы хотите, чтобы расположение элементов меньше скакало, то можно увеличить значение item-tolerance. На иллюстрации ниже допуск равен половине длины машины, потому машины, по сути, размещаются слева направо и переезжают в другую полосу, только чтобы избежать очень длинного лимузина. Теперь контент сгруппирован по горизонтали так: 1, 2, 3, 4, а потом 5, 6, 7.

Допуск можно сравнить с степенью терпеливости водителей. Захотят ли они менять полосу только для того, чтобы оказаться на несколько сантиметров впереди, или они переместятся, только если в другой полосе много места? Весомую для них величину пространства можно задать в item-tolerance.
Помните, что люди, перемещающиеся по странице с помощью Tab, будут видеть каждый элемент в фокусе выделенным, и могут потреблять информацию страницы через программу чтения экрана. Слишком большое значение item tolerance может привести к неприятным скачкам вверх и вниз по макету. Слишком малое значение допуска может привести к нежелательным переходам туда и обратно. Настраивайте item-tolerance так, чтобы значение соответствовало размерам и вариациям размеров вашего контента.
В настоящее время это свойство называется item-tolerance в спецификации и в Safari Technology Preview 234. Однако всё ещё есть вероятность того, что его название поменяется, возможно, на что-то типа flow-tolerance или pack-tolerance. Если вам нравится какое-то из названий или вы придумали что-то получше, то можете поделиться мнением. Прежде, чем использовать это свойство на веб-сайтах в продакшене, посмотрите, какое окончательное название выберут для этого свойства.
Попробуйте демо
Попробуйте Grid Lanes в Safari Technology Preview 234! Все демо на webkit.org/demos/grid3 были дополнены новым синтаксисом, в том числе и другие сценарии использования Grid Lanes. Они полезны не только для изображений! Например, огромный футер меню с кучей ссылок внезапно оказывается удобным.

.container {
display: grid-lanes;
grid-template-columns: repeat(auto-fill, minmax(max-content, 24ch));
column-gap: 4lh;
}
Что дальше?
CSS Working Group предстоит принять несколько последних решений. Но в целом, фича уже готова к применению в виде, описанном в этой статье. Пришла пора её использовать. И наконец-то уже можно запоминать её базовый синтаксис!
Было бы здорово, если бы вы создали демо! Покажите, какие новые сценарии использования вы сможете придумать. И сообщайте нам о найденных багах или возможных улучшениях. Ссылки, комментарии и идеи отправляйте Джен Симмонс в Bluesky или Mastodon.
Наша команда работала над этой фичей с середины 2022 года, реализуя её в WebKit и участвуя в составлении стандарта веба. Нам не терпится увидеть, что получится у вас с её помощью.