Альтернативное предложение по каменной кладке CSS

Команда Chrome очень хочет увидеть реализацию макетов каменной кладки в Интернете. Однако мы считаем, что реализация его как части спецификации CSS Grid, предложенная в недавнем сообщении о WebKit, была бы ошибкой. Мы также считаем, что сообщение о WebKit выступает против версии каменной кладки, которую никто не предлагал.

Поэтому цель этой статьи — объяснить, почему у нас в Chrome есть опасения по поводу реализации каменной кладки как части спецификации CSS Grid Layout, и прояснить, что именно позволяет альтернативное предложение. Суммируя:

  • Команда Chrome очень хочет разблокировать каменную кладку, мы знаем, что этого хотят разработчики.
  • Добавление каменной кладки в спецификацию сетки проблематично по причинам, не связанным с тем, считаете ли вы каменную кладку сеткой или нет.
  • Определение каменной кладки вне спецификации сетки не препятствует использованию нескольких размеров дорожек для каменной кладки или использованию таких свойств, как выравнивание или зазоры, а также любых других функций, используемых в макете сетки.

Должна ли каменная кладка быть частью сетки?

Команда Chrome считает, что masonry должен быть отдельным методом макета , определяемым с помощью display: masonry (или другого ключевого слова, если будет выбрано лучшее имя). Далее в этом посте вы сможете увидеть несколько примеров того, как это может выглядеть в коде.

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

Производительность

Сетка и кладка противоположны с точки зрения того, как браузер обрабатывает размеры и размещение. При макете сетки все элементы размещаются до макета, и браузер точно знает, что находится на каждой дорожке. Это позволяет использовать сложные внутренние размеры, которые так полезны в сетке. При использовании кладки элементы размещаются так, как они расположены, и браузер не знает, сколько их находится на каждой дорожке. Это не проблема для всех дорожек собственного размера или всех дорожек фиксированного размера, но возникает, если вы смешиваете фиксированные и внутренние дорожки. Чтобы обойти эту проблему, браузеру необходимо выполнить предварительную компоновку макета, разложив каждый элемент всеми возможными способами, чтобы получить размеры, а с большой сеткой это может привести к проблемам с производительностью макета.

Поэтому, если у вас есть каменная кладка с определением дорожки grid-template-columns: 200px auto 200px — очень распространенная вещь в сетке — вы начинаете сталкиваться с проблемами. Эти проблемы становятся экспоненциальными, как только вы добавляете подсетки .

Есть аргумент, что большинство людей не столкнутся с этим, однако мы уже знаем, что у людей действительно очень большие сетки . Мы не хотим выпускать что-то, что имеет ограничения на использование, когда есть альтернативный подход.

Что нам делать с вещами, которые не имеют смысла в каждом методе компоновки?

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

Объединение каменной кладки в сетку разрушает эту четкую связь между контекстом форматирования и доступностью таких вещей, как свойства выравнивания, которые определены в спецификации Box Alignment для каждого контекста форматирования.

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

Существуют также шаблоны, которые имеют смысл в каменной кладке, например grid-template-columns: repeat(auto-fill, max-content) , поскольку у вас нет перекрестных ограничений, но они должны оставаться недействительными в сетке. Ниже приведен список свойств, которые, как мы ожидаем, будут вести себя по-разному или иметь другие допустимые значения.

  • grid-template-areas : в каменной кладке вы можете указать только начальную строку в направлении, отличном от каменной кладки.
  • grid-template : Сокращение должно учитывать все различия.
  • Отслеживайте значения размеров для grid-template-columns и grid-template-rows из-за различий в допустимых значениях.
  • grid-auto-flow не применяется к каменной кладке, а masonry-auto-flow не применяется к сетке. Их объединение создаст проблемы с вещами, которые недействительны из-за используемого вами метода макета.
  • Grid имеет четыре свойства размещения ( grid-column-start и т. д.), а masonry — только два.
  • Grid может использовать все шесть свойств justify-* и align-* , но Masonry использует только их подмножество, например flexbox.

Также будет необходимо указать, что происходит во всех новых случаях ошибок, вызванных использованием разработчиками значения, которое недопустимо в сетке с каменной кладкой или в сетке без каменной кладки. Например, допустимо использовать grid-template-columns: masonry или grid-template-rows: masonry но не то и другое одновременно. Что произойдет, если вы используете оба одновременно? Эти данные необходимо указать, чтобы все браузеры выполняли одно и то же.

Все это усложняется с точки зрения спецификации сейчас и в будущем. Нам нужно будет следить за тем, чтобы все учитывало каменную кладку, а также работает или не работает она в каменной кладке. Это также сбивает с толку с точки зрения разработчиков. Почему вам нужно помнить, что, несмотря на использование display: grid некоторые вещи не работают из-за использования каменной кладки?

Альтернативное предложение

Как уже упоминалось, команда Chrome хотела бы определить кладку за пределами спецификации сетки. Это не означает, что он будет ограничен очень простым методом макета с одинаковыми размерами столбцов. Все демонстрации в статье о WebKit по-прежнему возможны.

Классическая каменная планировка

Когда большинство людей думают о каменной кладке, они представляют себе планировку с несколькими колоннами одинакового размера. Это будет определено с использованием следующего CSS, для которого требуется меньше строк кода, чем для эквивалентной версии в комплекте с сеткой .

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}

Дорожки одинакового размера.

Используйте размер дорожки типа сетки для столбцов разной ширины.

Помимо ранее упомянутой проблемы со смешанным собственным и фиксированным размером дорожек, вы можете использовать все размеры дорожек, которые вам нравятся, из сетки. Например , пример из записи блога WebKit , шаблон повторения узких и более широких столбцов.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, minmax(8rem, 1fr) minmax(16rem, 2fr)) minmax(8rem, 1fr);
  gap: 1rem;
}

Узор из широких и узких дорожек.

Дополнительные размеры направляющих для каменной кладки

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

Автозаполнение дорожек с max-content .

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, max-content);
  gap: 1rem;
}

Автозаполнение дорожек auto размером: создаются дорожки одинакового размера, автоматически подгоняемые под самую большую из них.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
  gap: 1rem;
}

Кладка с гусеницами автоматического размера.

Разрешить содержимому охватывать столбцы и размещать элементы на макете кладки.

Нет причин не включать столбцы содержимого в отдельную спецификацию кладки. Здесь может использоваться свойство masonry-track , являющееся сокращением для masonry-track-start и masonry-track-end поскольку в макете каменной кладки у вас есть только одно измерение, чтобы охватить объекты.

.masonry {
  display: masonry;
  masonry-template-tracks: repeat(auto-fill, auto);
}

.span-2 {
  masonry-track: span 2; /* spans two columns */
}

.placed {
  masonry-track: 2 / 5; /* covers tracks 2, 3, and 4 */
}

Кладка с размещенными и пролетными элементами.

Подкладка или подрешетка с каменными направляющими

Это может быть подкреплено отдельной спецификацией каменной кладки, опять же с оговоркой, что смешанные дорожки собственного и фиксированного размера запрещены. Необходимо будет точно определить, как это будет выглядеть. Мы не видим причин, по которым это не сработает.

Заключение

Нам бы хотелось дойти до такой спецификации, которая могла бы поставляться интероперабельно. Однако мы хотим сделать это таким образом, чтобы это работало хорошо сейчас и в будущем и на которое могли бы положиться разработчики. Единственный способ справиться с изложенными проблемами производительности — усугубить вторую проблему — недопустимое использование частей сетки в каменной кладке. Мы не думаем, что это хорошее решение, особенно когда можно иметь все нужные функции сетки, сохраняя при этом четкое разделение различных элементов.

Если у вас есть отзывы, присоединяйтесь к обсуждению в выпуске 9041 .

Спасибо Брамусу, Табу Аткинс-Биттнеру, Уне Кравец, Яну Килпатрику и Крису Харрельсону за рецензирование этого поста и обсуждения, которые послужили его основой.