CSS-сетка с автозаполнением строк с автоматическим размером

Я хотел бы создать сетку элементов, которая размещает столько элементов в каждой строке, сколько может поместиться. Должно:

  • Автоматически изменять размер столбцов в соответствии с их элементами
  • Автоматически добавлять/удалять столбцы в соответствии с контейнером

По сути, я ищу таблицу со столбцами автоматического размера и автоматическим количество столбцов. 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-таблица с неопределенным количеством столбцов.

У меня была такая же проблема целую вечность, я не думаю, что есть элегантное решение

Zach Jensz 06.04.2022 01:16
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
3
1
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это требование приводит к противоречивым сценариям:

Допустим, есть 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. (Я не возражаю, если все столбцы имеют одинаковую ширину, но я просто не знаю, какой будет эта ширина априори.)

mgiuffrida 08.04.2022 05:50

Вы не знаете ширину содержимого ячейки естественный, но вы все равно можете рассматривать ячейки как контейнеры и устанавливать их ширину на фиксированное значение, например width: 400px; max-width: 100vw. В любом случае вам нужно ограничить ширину определенным значением, иначе большой абзац текста приведет к одной очень длинной строке, которую вы, вероятно, не хотите иметь.

Knight Industries 08.04.2022 07:09

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

mgiuffrida 09.04.2022 17:30

Тем не менее, спасибо за предложения и за указание на противоречивые требования! Вероятно, вы правы в том, что не существует решения, основанного только на CSS, для того, чего я пытаюсь достичь, поэтому я отмечаю это как ответ.

mgiuffrida 09.04.2022 17:35

Css width устанавливает ширину. Если это контейнер и его содержимое меньше, ширина останется прежней. Если содержимое шире, вы можете управлять поведением с помощью overflow.

Knight Industries 09.04.2022 17:48

Если вы ищете макет каменной кладки. Спецификация 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. В черновике спецификации говорится: «Элементы помещаются в столбец (или строку) с наибольшим оставшимся пространством в зависимости от размера макета элементов, размещенных до сих пор», что, я думаю, не то, что я хочу.

mgiuffrida 09.04.2022 17:34

Другие вопросы по теме