Как стать автором
Обновить

Нативный Masonry Layout в CSS Grid Level 3

Время на прочтение6 мин
Количество просмотров34K
Автор оригинала: Rachel Andrew

Приветствую. Представляю вашему вниманию перевод статьи «Native CSS Masonry Layout In CSS Grid», опубликованной 2 ноября 2020 года автором Rachel Andrew

Недавно был опубликован черновик спецификации CSS Grid 3 уровня, в котором содержится описание способа создания Masonry-раскладки с помощью чистого CSS. В этой статье Rachel Andrew объясняет данную спецификацию с примерами, которые вы можете воспроизвести в браузере Firefox Nightly. И хотя данный функционал пока что нельзя использовать в реальных проектах, ваш отзыв может помочь убедиться, что текущая реализация соответствует или не соответствует требованиям разработчиков к этому типу раскладки. Итак, приступим.

Что такое Masonry-раскладка?

При masonry-раскладке элементы располагаются один за другим в строчном направлении. При переносе на новую строку они могут смещаться вверх, заполняя пространство, оставленное коротким элементом, расположенным на предыдущей строке текщей колонки. Это похоже на Grid-разметку с автоматическим расположением элементов, но строгого выравнивания по вертикали.

Наиболее известный пример masonry-раскладки – это Pinterest, и вы могли слышать, как её порой даже называют "Pinterest-раскладкой".

Существует множество JavaScript-инструментов, помогающих добиться такого эффекта. Например, Masonry plugin от David DeSandro’s.

Разве сейчас это невозможно?

Приблизиться к Masonry можно с помощью нескольких способов. Самый простой из них – использовать Мультиколонки (раскладку в несколько столбцов). В примере ниже расположение элементов визуально напоминает Masonry. Однако, блоки располагаются в колонках один под другим. Из-за этого вверху такой раскладки будут располагаться элементы, расположенные не в начале списке. А это может быть критически важно, например, при отображении результатов поиска.

Второй способ - CSS Grid. Когда дизайнеры впервые видели Grid-раскладку, часто думали, с помощью автоматического расположения элементов в плотном (dense) режиме можно достичь вида, подобного Masonry. Но это по-прежнему сетка, следовательно не получится заставить элементы занимать свободное место по вертикали, оставленное другими короткими элементами.

Вывод – для получения Masonry всё ещё необходимо использовать JavaScript. А создание раскладки с помощью JavaScript, особенно при большом количестве элементов, не идёт на пользу производительности. Я сразу указала на то, что веб-разработчики просили этот функционал ещё в Январе 2017 года. И хотя у меня есть некоторые опасения касательно того, действительно ли следует делать Masonry частью CSS Grid, а также касательно проблем с доступностью из-за изменения порядка содержимого, я рада, что в этом направлении ведётся активная работа.

Режим Masonry в CSS Grid

Это новая спецификация, поэтому некоторые моменты могут измениться, прежде чем начнут поддерживаться большинством браузеров. Но поскольку этот функционал уже реализован в Firefox, мы можем опробовать его уже сейчас. Для этого скачайте Firefox Nightly и в разделе about:config активируйте флаг layout.css.grid-template-masonry-value.enabled. После этого все демонстрации будут работать корректно.

Чтобы реализовать Masonry-раскладку, одна из осей Grid-контейнера должна иметь свойство grid-template-* со значением masonry. Она будет называться "masonry-осью". Строки и колонки на другой оси будут определены как обычно, это будет "grid-ось". Приведённый ниже CSS создаёт четырёхколоночную сетку, в которой строки установлены в значение masonry. Masonry-элементы будут отображаться в четырёх колонках grid-оси.

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

Это всё, что нужно, чтобы получить простую masonry-раскладку. С помощью Firefox Nightly можно посмотреть реальный Codepen-пример ниже.

Собственно, на этом можно было и остановиться, но так как функционал Masonry становится частью CSS Grid, мы можем использовать и другие возможности данной спецификации, даже когда находимся в режиме "Masonry". Следовательно спецификация требует определения этих моментов.

Поведение Grid-оси

Ось, на которой просто определяются треки, ведёт себя стандартно. Следовательно, можно задавать размер треков, имена линий и использовать выравнивание точно так же, как это делается в обычной сетке.

Также, с помощью линий на оси можно располагать элементы. Они будут добавлены на сетку перед добавлением masonry-элементов. Я добавила изображение с подписью "5" между линией box-start и линией box-end. Masonry-элементы расположились вокруг данного изображения.

Также можно изменять span - количество треков, которые охватывает элемент как на обычной grid-оси. В следующем примере нескольким элементам задан класс landscape. При размещении в режиме masonry-раскладки, эти элементы занимают два колоночных трека.

Свойство "masonry-auto-flow"

Описание masonry в спецификации вводит дополнительные свойства в Grid-раскладку. Свойство masonry-auto-flow ещё не добавлено в Firefox. Но когда это произойдёт, оно даст контроль над потоком элементов в Masonry-раскладке.

Если задать masonry-auto-flow: next, каждый последующий элемент будет размещаться на следующей позиции grid-оси, а не в колонке с наибольшим количеством места, как происходит по умолчанию.

Свойство masonry-auto-flow: ordered приведёт к тому, что masonry будет игнорировать элементы, точно спозиционированные на сетке и вместо этого будет использовать обычный порядок элементов в документе (исключение - изменение номера элемента в последовательности с помощью свойства "order").

Свойства "justify-tracks" и "align-tracks"

На момент написания статьи, данные свойства частично работают в Firefox Nightly. Это свойства дополнительного выравнивания masonry-раскладки. Если у вас masonry в блочном направлении, можно использовать align-tracks, если в строчном - justify-tracks.

Если в grid-контейнере остаётся дополнительное пространство в оси, в которой располагается masonry, вы можете обнаружить, что элементы выравниваются по начальной стороне контейнера. Начальным значением свойства align-tracks (в нашем случае с masonry, создаваемой для строк) является start.

Эти свойства работают вместе с align-content и justify-content. Как это происходит, продемонстрировано в следующем примере, где grid-контейнер имеет высоту, равную 200vh. Для свойства align-track я устанавливаю значение end.

Если установлено значение normal (что будет, если я не задам свойство), то masonry-треки окажутся в конце контейнера.

Если я добавлю align-content: start, masonry-треки вернутся в начало контейнера. Однако, теперь «выступающие края» раскладки вверху, а не внизу потому что masonry-треки выровнены по конечной стороне.

Примечание: вы можете использовать любые значения, применяемые к свойствам align-content, align-tracks или justify-tracks. В спецификации есть несколько хороших примеров различных комбинаций.

Если задать align-track: stretch, любые элементы с автоматическим размером будут растянуты. Masonry-эффект сохранён, но все элементы данной оси, имеющие определённый размер, не будут растягиваться.

Свойства align-tracksи justify-tracks могут принимать несколько значений. По одному для каждого трека оси сетки. Это значит, что в нашей сетке с четырьмя треками, первый трек может быть растягивающимся, второй - выровненным по начальной стороне, третий - по конечной, четвёртый - по центру.

На момент написания статьи в Firefox это не работало.

В спецификации указано, что если значений меньше, чем треков, оставшиеся треки будут использовать последнее указанное значение. Если значений больше, чем треков, лишние значения будут проигнорированы.

FALLBACK-поведение

Включение этого функционала в спецификацию CSS Grid имеет определённое преимущество, когда речь идёт о создания фолбэк-раскладки. Поскольку masonry ведёт себя так же, как автоматическое размещение, если браузер её не поддерживает, вместо неё может использоваться обычное автоматическое размещение. В раскладке может возникнуть незаполненное пространство, как показано в примере выше, но это не так страшно.

Увидеть этот эффект в действии можно в любом приведённом выше демо, если использовать браузер, не поддерживающий masonry. Вы всё ещё получаете раскладку. Если же нужно было сделать что-то абсолютно другое, проверить наличие поддержки masonry можно с помощью feature queries. Например, для браузеров, не поддерживающих masonry, можно сделать раскладку с помощью мультиколонок.

@supports (grid-template-rows: masonry) {
  /* код masonry */
}

Если masonry-раскладка жизненно необходима, её поддержку можно проверить с помощью CSS.support и при необходимости использовать JavaScript-библиотеку. Это означало бы, что по мере внедрения браузерами поддержки masonry, решение на JavaScript уже не использовалось, но присутствовало бы в виде полифила.

Потенциальные проблемы с совместимостью

Хотя masonry в CSS - это здорово, есть ещё одно место, где порядок содержимого в документе может отличаться от того, как оно в итоге выводится на экран. Как я указывала в недавнем issue, думаю, мы создаём потрясающием возможности для разметки, а потому должны донести до людей необходимость быть осторожными в их использовании.

Я писала об этой проблеме в статье «Grid, content re-ordering and accessibility». Надеюсь, что по мере развития спецификации, также будут возобновлены усилия по улучшению способов работы с содержимым и порядком отображения.

Ваш мнение важно

Нам очень повезло не только с этой новой спецификацией, но и с тем, что есть возможность протестировать её в браузере. Если вы где-то используете masonry-раскладку, почему бы не попробовать заменить JavaScript-решение на CSS Grid и посмотреть, как оно будет работать? Если столкнётесь с проблемами или не сможете осуществить что-то, что могли до этого, сообщите об этом в CSSWG, создав issue.

Теги:
Хабы:
Всего голосов 6: ↑5 и ↓1+8
Комментарии4

Публикации

Истории

Ближайшие события

25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань