Я хотел бы создать сетку элементов, которая размещает столько элементов в каждой строке, сколько может поместиться. Должно:
По сути, я ищу таблицу со столбцами автоматического размера и автоматическим количество столбцов. Flexbox с flex-wrap
у меня не работает, так как столбцы не будут выровнены.
Я пытался использовать grid
с auto-fill
, но не могу понять, как обеспечить рост каждого столбца в соответствии с его содержимым. В этом примере это работает, только если я укажу фиксированную минимальную ширину, например:
grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
Я попытался заменить функцию minmax
на auto
, но это приводит к тому, что каждый столбец занимает 100% ширины. Есть ли другой способ добиться того, что я пытаюсь сделать (без JavaScript)?
div {
width: 300px;
border: 1px solid red;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
}
<div>
<span>word</span>
<span>word</span>
<span>longword</span>
<span>word</span>
<span>longword</span>
<span>word</span>
<span>word</span>
<span>word</span>
<span>word</span>
<span>word</span>
<span>word</span>
<span>word</span>
<span>word</span>
<span>word</span>
</div>
Мой желаемый макет будет выглядеть точно так же, как показано выше, за исключением того, что любые столбцы, содержащие ячейку «длинное слово», будут достаточно широкими, чтобы соответствовать этой ячейке (и количество столбцов при необходимости сократится). Конечным результатом будет несколько столбцов с автоматическим изменением размера, каждый из которых будет настолько широким, насколько это необходимо, чтобы соответствовать содержимому их ячеек. По сути, HTML-таблица с неопределенным количеством столбцов.
Это требование приводит к противоречивым сценариям:
Допустим, есть 6 ячеек со следующими длинами в указанном порядке:11111
, 2
, 3
, 44444
, 5
, 6
3 столбца → ширина: 7
|11111|2|3| |44444|5|6|
2 столбца → ширина: 10
|11111|2 | |3 |44444| |5 |6 |
⚠️ Уменьшение количества столбцов для небольших экранов приведет к сетке Шире в этом случае, и она больше не подходит.
Это как минимум одна из причин, по которой компоновка такой сетки может быть сложной задачей, не поддерживается CSS и почему это, вероятно, не очень хорошая идея в целом.
Предложения (только CSS):
flex-wrap
и сделайте все ячейки одинаковой ширины, если они должны быть выровнены.Спасибо за предложения. Я не знаю ширину содержимого, поэтому не могу определить ширину вручную. Я рассмотрю решение JS. (Я не возражаю, если все столбцы имеют одинаковую ширину, но я просто не знаю, какой будет эта ширина априори.)
Вы не знаете ширину содержимого ячейки естественный, но вы все равно можете рассматривать ячейки как контейнеры и устанавливать их ширину на фиксированное значение, например width: 400px; max-width: 100vw
. В любом случае вам нужно ограничить ширину определенным значением, иначе большой абзац текста приведет к одной очень длинной строке, которую вы, вероятно, не хотите иметь.
Важно, чтобы ячейки были как можно более узкими в зависимости от их содержимого. Фиксированная ширина 400 пикселей обеспечивает минимальную ширину 400 пикселей, верно?
Тем не менее, спасибо за предложения и за указание на противоречивые требования! Вероятно, вы правы в том, что не существует решения, основанного только на CSS, для того, чего я пытаюсь достичь, поэтому я отмечаю это как ответ.
Css width
устанавливает ширину. Если это контейнер и его содержимое меньше, ширина останется прежней. Если содержимое шире, вы можете управлять поведением с помощью overflow
.
Если вы ищете макет каменной кладки. Спецификация CSS для него все еще находится на уровне проекта ссылка.
Однако вы можете попробовать спецификацию в Firefox v77 и выше. ссылка
В about:config
установите предпочтение layout.css.grid-template-masonry-value.enabled
на true
и попробуйте эту демонстрацию:
div {
padding: .5rem;
width: 300px;
display: grid;
gap: 10px;
grid-template-columns: masonry;
grid-template-rows: repeat(4, auto);
border: 1px solid red;
}
div span {
display: inline-block;
padding: .5rem;
border: 1px solid orange;
border-radius: .5rem;
}
Works only in Firefox v77 and above!
<div>
<span>word</span>
<span>word</span>
<span>longword</span>
<span>word</span>
<span>longword</span>
<span>word</span>
<span>word</span>
<span>word</span>
<span>word</span>
<span>long long very long text</span>
<span>word</span>
<span>word</span>
<span>word</span>
<span>word</span>
</div>
Для тех, у кого не установлен Firefox, вот как это выглядит:
Доступны дополнительные демоверсии здесь
На данный момент вам придется использовать решения на основе JavaScript, такие как:
Очень круто, но в моем вопросе указано, что столбцы должны быть выровнены. Ваш пример очень похож на flex с flex-wrap. В черновике спецификации говорится: «Элементы помещаются в столбец (или строку) с наибольшим оставшимся пространством в зависимости от размера макета элементов, размещенных до сих пор», что, я думаю, не то, что я хочу.
У меня была такая же проблема целую вечность, я не думаю, что есть элегантное решение