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

Опубликовано: 30 апреля 2024 г., Последнее обновление: 13 февраля 2026 г.

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

Таким образом, цель этой статьи — объяснить, почему у нас в Chrome есть опасения по поводу внедрения макета Masonry в спецификацию CSS Grid Layout, и прояснить, что именно позволяет предлагаемый альтернативный вариант. Вкратце:

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

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

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

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

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

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

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

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

Что делать с тем, что не имеет смысла в каждом из методов компоновки?

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

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

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

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

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

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

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

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

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

Классическая каменная кладка

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

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

Пути одинакового размера.

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

Помимо упомянутой ранее проблемы со смешанным внутренним и фиксированным размером дорожек, вы можете использовать все любимые вами размеры дорожек из пакета grid. Например, как в примере из статьи в блоге 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 .

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