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 может сильно упростить нам жизнь и дать новые инструменты для креативной вёрстки.