Item Flow: объединяем флексы, гриды и Masonry в единый инструмент
Сегодня я хочу поделиться идеей, которая объединяет флексы и гриды в нечто совершенно новое и, возможно, приведёт нас к полноценной нативной Masonry‑раскладке в CSS. Ниже я расскажу об этой задумке, которую сейчас обсуждает Apple, Google, W3C и многие другие команды, и объясню, почему это важно.
Зачем нам Item Flow
Флексы и гриды уже подарили нам мощные инструменты для построения сложных макетов. Но, увы, до сих пор невозможно из коробки реализовать популярный «masonry» (или «waterfall») — ту самую «каскадную» раскладку, когда блоки с разной высотой (или шириной) складываются подобно кирпичикам без ровных строк и столбцов.
Раскладка Masonry
Обычно для такого эффекта приходится подключать JavaScript‑библиотеки.
Несколько лет назад разные команды браузеров попытались внедрить Masonry в движок, и в итоге появились две основные конкурирующие концепции:
- Just Use Grid. Предлагалось добавить в гриды специальную «обрушенную» стратегию для строк/столбцов.
- New Masonry Layout. Идея сделать отдельное значение у
display
(например,display: masonry
).
Однако Техническая Рабочая Группа (W3C TAG) высказала мысль: почему бы не объединить Masonry, флексы и гриды в единый набор свойств, чтобы вёрстка стала более универсальной, а мы получили гибкий инструмент для всех трёх задач разом?
Так родилась идея Item Flow.
Что такое Item Flow
Сегодня у нас есть два свойства для управления «потоком» элементов:
flex-flow
(для флексов)grid-auto-flow
(для гридов)
Item Flow хочет заменить и расширить их с помощью новых свойств и значений, чтобы разработчик мог одинаково управлять направлением, переносом, «упаковкой» и другими нюансами — и в гридах, и во флексах, и в будущем Masonry.
Три кита нового подхода
-
Универсальное направление
Вместо
flex-direction
и частиgrid-auto-flow
(row
,column
) появится единое свойство:item-direction: row | column | row-reverse | column-reverse;
Оно определяет, будет ли всё располагаться в строку или в столбец, в прямом или в обратном порядке.
-
Гибкий перенос
Флексы давно умеет переносить элементы (
flex-wrap
), а гриды по умолчанию уже создаёт новые ряды. Но теперь всё это становится единым механизмом:item-wrap: auto | nowrap | wrap | normal | reverse;
auto
— поведение по умолчанию (как сегодня: флексы не переносит, гриды переносит).nowrap
— отключение переноса (но теперь и для гридов; это позволит сделать, например, одну строку с фиксированным количеством колонок 1fr).wrap
илиnormal
— обычный перенос.reverse
— перенос в обратном направлении (аналогwrap-reverse
для флексов).
-
Способы «упаковки» Сегодня у гридов есть «плотный» режим (
dense
), а у флексов только стандартный.item-pack
может это объединить:item-pack: normal | dense | balance | collapse ...;
normal
— стандартная «неплотная» раскладка.dense
— попытки уплотнять и заполнить пустые места (в гридах уже есть, для флексов обсуждается, как именно это лучше работать).balance
— потенциальный новый режим, когда элементы распределяются по строкам более равномерно (чтобы не было ситуации «5 элементов в первой строке и 1 во второй»).collapse
(или похожее значение) — возможный триггер для Masonry‑раскладки. Вместо жёстких рядов и столбцов элементы «обрушаются» так, чтобы минимизировать пустоты.
Таким образом, Masonry может быть не grid-template-rows: collapse;
и не display: masonry;
, а, например, item-pack: collapse;
. И при этом мы используем единый подход как для гридов, так и для флексов.
А что за item-slack
?
Ещё одна новая идея — свойство item-slack
, которое задаёт «толерантность» при решении, помещать ли элемент в текущую строку/колонку или переносить. Оно особенно важно для Masonry, когда браузер «ищет» колонку с минимальным остатком по высоте.
Но и в флексам это может пригодиться: скажем, item-slack: 1em
даёт команду «если элемент чуть-чуть не влезает, всё равно постарайся его вместить, чуть ужав остальное».
Название пока обсуждается. Возможно, появятся другие варианты: threshold
, tolerance
и т.д.
Пример общего синтаксиса
.container {
display: flex; /* или grid */
item-flow: row wrap dense;
}
Или подробно:
.container {
display: flex;
item-direction: row;
item-wrap: wrap;
item-pack: dense;
}
Здесь заложен потенциал для того, чтобы объединить всю логику «потоков» в одном месте, вместо зависимости от кучи разрозненных свойств.
Почему это может изменить всё
- Grid без переноса. Наконец-то можно легко собрать всё содержимое в одну строку, распределив элементы равномерно на 1fr.
- Плотная упаковка во флексах. Теперь не нужно городить костыли, когда хочется «впихнуть» ещё один элемент в строку, если там остаётся чуть-чуть места.
- Сбалансированная укладка. Никто не любит, когда в последней строке остаётся один блок, а все остальные загружают первую строку. Новый режим
balance
может это исправить. - Masonry без ухищрений. Настоящее «обрушение» строк или столбцов, без подключения внешних JS‑плагинов.
Мы стоим на пороге больших перемен в мире CSS: объединение флексов, гридов и Masonry в рамках Item Flow может сильно упростить нам жизнь и дать новые инструменты для креативной вёрстки.