CSS 具有自动调整大小的自动填充行的网格

CSS grid with auto-sized auto-filled rows

我想创建一个项目网格,在每行中放置尽可能多的项目。它应该:

实际上,我正在寻找具有自动调整大小的列和自动 number 列的 table。 flex-wrap 的 Flexbox 对我不起作用,因为列不会对齐。

我试过将 gridauto-fill 一起使用,但我无法弄清楚如何确保每列增长以适应其内容。在此示例中,它仅在我指定固定的最小宽度时才有效,例如:

grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));

我尝试用 auto 替换 minmax 函数,但这会导致每列占用 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>

我想要的布局看起来就像上面那样,只是任何包含“longword”单元格的列都足够宽以适合该单元格(并且列数会缩减,如果需要的话)。最终结果将是几个自动调整大小的列,每个列的宽度仅在适合其单元格内容的必要范围内。基本上,HTML table 具有不确定的列数。

此要求导致矛盾的情况:

假设有 6 个单元格按特定顺序具有以下长度:
11111234444456

  • 3 列 → 宽度:7

    |11111|2|3|
    |44444|5|6|
    
  • 2 列 → 宽度:10

    |11111|2    |
    |3    |44444|
    |5    |6    |
    

⚠️ 减少较小屏幕的列数会导致 更宽 网格,在这种情况下它不再适合。

这至少是为什么这样的网格布局可能是一项复杂的任务,不受 CSS 支持以及为什么它通常不是一个好主意的原因之一。

建议(CSS-only):

  • 使用媒体查询手动定义每个屏幕尺寸的列数
  • 或者只使用 flex-wrap 并使所有单元格宽度相同(如果它们应该对齐)。

如果您正在寻找砖石布局。它的 CSS 规范仍处于草案级别 ref

但是,您可以在 Firefox v77 及更高版本中尝试该规范。 ref
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 的人,它看起来是这样的:

有更多演示可用here


现在您必须使用基于 JavaScript 的解决方案,例如: