Мне нужно реализовать довольно нестандартную планировку кладки. Однако по ряду причин я не хочу использовать для этого JavaScript.
Параметры:
- Все элементы имеют одинаковую ширину
- Элементы имеют высоту, которую невозможно вычислить на стороне сервера (изображение плюс различное количество текста)
- Я могу жить с фиксированным количеством столбцов, если мне нужно
есть тривиальное решение, которое работает в современных браузерах - column-count
свойство.
Проблема с этим решением в том, что элементы упорядочены по столбцам:
Пока мне нужно, чтобы элементы были упорядочены по строкам, хотя бы примерно:
Подходы, которые я пробовал, не работают:
- Изготовление предметов
display: inline-block
: тратит вертикальное пространство. - Изготовление предметов
float: left
: лол, нет.
Теперь я мог бы изменить рендеринг на стороне сервера и переупорядочить элементы, разделив количество элементов на количество столбцов, но это сложно и подвержено ошибкам (в зависимости от того, как браузеры решают разделить список элементов на столбцы), поэтому я хотел бы по возможности избегать этого.
Есть ли какая-то новомодная магия flexbox, которая делает это возможным?
Ответы:
Flexbox
Динамическая разметка каменной кладки невозможна с помощью flexbox, по крайней мере, в чистом и эффективном виде.
Flexbox - это система одномерного макета. Это означает, что он может выравнивать элементы по горизонтальным ИЛИ вертикальным линиям. Гибкий элемент ограничен своей строкой или столбцом.
Настоящая сетка двумерна, то есть она может выравнивать элементы по горизонтальным И вертикальным линиям. Элементы содержимого могут одновременно охватывать строки и столбцы, чего не могут сделать гибкие элементы.
Вот почему возможности flexbox для построения сеток ограничены. Это также причина, по которой W3C разработал другую технологию CSS3, Grid Layout .
row wrap
В гибком контейнере с
flex-flow: row wrap
гибкими элементами должны быть перенесены в новые строки .Это означает, что гибкий элемент не может быть перенесен под другой элемент в той же строке .
Обратите внимание на то, как div # 3 оборачивается под div # 1 , создавая новую строку. Он не может быть заключен в div # 2 .
В результате, когда элементы не самые высокие в ряду, остается пустое пространство, создавая неприглядные зазоры.
column wrap
Если вы переключитесь на
flex-flow: column wrap
, сетка станет более доступной. Однако контейнер с направлением столбца сразу же имеет четыре потенциальных проблемы:В результате контейнер в направлении столбца не подходит в этом случае, как и во многих других случаях.
CSS Grid с неопределенными размерами элементов
Макет сетки был бы идеальным решением вашей проблемы, если бы можно было заранее определить различную высоту элементов контента . Все остальные требования находятся в пределах возможностей Grid.
Необходимо знать ширину и высоту элементов сетки, чтобы закрыть пробелы с окружающими элементами.
Таким образом, Grid, который является лучшим CSS, который может предложить для построения горизонтального макета кирпичной кладки, в этом случае не справляется.
Фактически, пока не появится технология CSS, способная автоматически закрывать пробелы, у CSS вообще нет решения. Что-то вроде этого, вероятно, потребует перекомпоновки документа, поэтому я не уверен, насколько это будет полезно или эффективно.
Вам понадобится сценарий.
Решения JavaScript, как правило, используют абсолютное позиционирование, которое удаляет элементы контента из потока документов, чтобы переупорядочить их без пропусков. Вот два примера:
Desandro Masonry
Как создать сайт, который работает как Pinterest
CSS Grid с определенными размерами элементов
Для макетов, в которых известны ширина и высота элементов содержимого, вот горизонтальный макет кладки на чистом CSS:
демонстрация jsFiddle
Как это устроено
inline-grid
был бы другой вариант)grid-auto-rows
Свойство задает высоту автоматически генерируемых строк. В этой сетке каждая строка имеет высоту 50 пикселей.grid-gap
Свойство является обобщающим дляgrid-column-gap
иgrid-row-gap
. Это правило устанавливает промежуток в 10 пикселей между элементами сетки. (Это не относится к области между предметами и контейнером.)grid-template-columns
Свойство устанавливает ширину явно определенных столбцов.repeat
Обозначения определяет образец повторяющихся столбцов (или строк).auto-fill
Функция сообщает сетку выстраиваться столько столбцов (или строк) , как это возможно без переполнения контейнера. (Это может создать поведение, подобное гибкому макетуflex-wrap: wrap
.)minmax()
Функция устанавливает минимальный и максимальный диапазон размеров для каждого столбца (или строки). В приведенном выше коде ширина каждого столбца будет составлять минимум 30% контейнера и максимум доступного свободного места.fr
Блок представляет собой долю свободного пространства в контейнере сетки. Это сопоставимо соflex-grow
свойством flexbox .С помощью
grid-row
иspan
мы сообщаем элементам сетки, сколько строк они должны занимать.Поддержка браузером CSS Grid
Вот полная картина: http://caniuse.com/#search=grid
Классная функция наложения сетки в Firefox
В инструментах разработчика Firefox, когда вы проверяете контейнер сетки, в объявлении CSS есть крошечный значок сетки. При щелчке он отображает контур вашей сетки на странице.
Подробнее здесь: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts
источник
Это недавно открытый метод с использованием flexbox: https://tobiasahlin.com/blog/masonry-with-css/ .
Эта статья имеет для меня смысл, но я не пробовал ее использовать, поэтому не знаю, есть ли какие-либо предостережения, кроме упомянутых в ответе Майкла.
Вот образец из статьи, в которой используется
order
свойство в сочетании с:nth-child
.Фрагмент стека
источник
order
свойства, что делает его похожим на движение элементов слева направо. Тем не менее, его главная хитрость в томflex-flow: column wrap
, что упоминается в ответе выше. Кроме того, он не может перемещать элементы так, как это делает настоящая кладка, например, если 3-й и 4-й элементы поместятся в 3-м столбце, они будут, а связанный - нет. Но опять же, как я уже сказал, все зависит от требований, и в этом случае (в этом вопросе) это не сработает так, как просили.