CSS 行数可变的网格 "auto",但其中一行应为“1fr”

CSS Grid with variable number of "auto" rows, but one row should take "1fr"

我正在摆弄一个 CSS 基于网格的前端,并且在前端的不同部分一遍又一遍地需要以下行为:

  1. 行数可变的网格。
  2. 每一行的大小都应该可变(自动就可以)。
  3. 最后一行应始终占据所有剩余 space。

所以如果我恰好需要五行,这就可以了:

.myGridForFiveRows
{
    display: grid;
    grid-template-rows: auto auto auto auto 1fr;
}

但是,我非常想要一个样式表,它可以为任何给定的行数生成正确的行为。我想也许我可以以某种方式使用 repeat() 来做到这一点?

https://developer.mozilla.org/en-US/docs/Web/CSS/repeat

.myGrid
{
    display: grid;
    grid-template-rows: repeat(auto-fit, auto) 1fr;
}

我一直在研究 repeat(auto-fit, auto)repeat(auto-fill, auto) 的变体,不幸的是它们不合法 CSS,而 repeat(4, auto)repeat(auto-fill, 30px)是。

有什么想法吗?这不是我无法规避的事情,但碰巧 "display n properly sized rows, then let the last element take up all the remaining space" 基本上是我规范中所有元素的默认行为...

考虑到您的三个要求:

  1. A grid with a variable number of rows.
  2. Every row should have a variable size (auto will do).
  3. The last row should always take up all the remaining space.

Flexbox 非常适合这项工作。事实上,它可能是最合适的(取决于您的其他要求)。我在下面提供了一个代码示例。

但是如果网格布局是您想要的,那么我想您会失望的。我不相信 Level 1 可以胜任这项工作。

最接近的是:

grid-template-rows: repeat(auto-fit, minmax(auto, 1px)) 1fr;

但它不会工作,因为当前的网格规范不支持此语法。

repeat(auto-fit, auto) 1fr

这是您试过的代码。它无效,因为 autofr 不能与 auto-fit 一起使用。

7.2.2.1. Syntax of repeat()

Automatic repetitions (auto-fill or auto-fit) cannot be combined with intrinsic or flexible sizes.

  • An intrinsic sizing function is min-content, max-content, auto, fit-content().

  • A flexible sizing function is <flex> (fr).

您可以通过以下方式绕过 auto 限制:

repeat(auto-fit, minmax(auto, 1px)) 1fr

minmax(min,max)

Defines a size range greater than or equal to min and less than or equal to max.

If max < min, then max is ignored and minmax(min,max) is treated as min.

As a maximum, a <flex> value sets the track’s flex factor; it is invalid as a minimum.

无论容器具有默认的 auto 高度还是定义的 height / min-height,这都可以正确地自动调整行的大小。 demo

但它仍然没有解决最后一行的问题,因为 1fr 仍然无效,并导致整个规则失败。 demo

像这样的东西是有效的:

repeat(auto-fit, minmax(auto, 1px)) 10em

但是 auto-fit 没有像您预期的那样工作:10em 应用于第二行。 demo

如果容器定义了 heightmin-height,则规则不会按预期工作。 demo


即使 CSS 网格布局现在广泛可用,Flexbox 在某些情况下仍然是更好的选择。

这用简洁明了的代码满足了您的所有要求:

article {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

section:last-child {
  flex-grow: 1;
}

section {
  /* flex-basis: auto <-- this is a default setting */
  margin-bottom: 10px;
  background-color: lightgreen;
}

body {
  margin: 0;
}
<article>
  <section>text text text</section>
  <section>text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text
    text text text text text text text text text text </section>
  <section>text text text text text text text text text text text text text text text text text text text text text text text text text text text</section>
  <section>text text text text text text text text text text text text text text text text text text text text text text text text text text text</section>
  <section>text text text text text text text text text text text text text text text text text text text text text text text text text text text</section>
</article>

这有点 hack,但您可以输入一个非常大的重复数字,您永远不会越过。例如,您可以为 grid-template-rows:

grid-template-rows:重复(100000000,自动)1fr;

我遇到了同样的问题,这对我有用。