CSS Grid有flex-grow功能吗?

62

是否有grid属性的类似于flex-grow的模拟方法?

我希望我的网格区域能够适应它们接收到的内容,但一些区域可以像flex-growflex一样占用更多的空间。

实际上,在下面的示例中:

  • turquoise应该是不可见的,因为它适应其内容。
  • footer也应该是不可见的,因为它没有内容。
  • 中间部分应该像flex-grow一样占据页面的剩余部分。

更具体地说,我想要这段代码:

.ctnr {
  display: grid;
  min-height: 100vh;
  grid-template-areas:
    "header header"
    "nav main"
    "footer footer";
}

.test {
  background: black;
  height: 1rem;
}

header {
  grid-area: header;
  background: turquoise;
}

nav {
  grid-area: nav;
  background: grey;
}

main {
  grid-area: main;
}

footer {
  grid-area: footer;
  background: yellow
}
<div class="ctnr">
  <header>
    <div class="test"></div>
  </header>
  <nav></nav>
  <main></main>
  <footer></footer>
</div>

表现为这段代码:

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

.panel {
  flex-grow: 1;
  display: flex;
}

header {
  flex-grow: 0;
  background: turquoise;
}

nav {
  min-width: 10rem;
  background: grey
}

footer {
  background: yellow
}
<div class="ctnr">
  <header>hey</header>
  <div class="panel">
    <nav></nav>
    <main></main>
  </div>
  <footer></footer>
</div>

不需要 div.panel,也不需要添加任何其他标记。

我之所以想这样做,是因为多一个 div 元素让我感到很烦。

2个回答

80
CSS Grid提供了fr单位,其功能类似于flex-grow
虽然flex-grow将容器中的自由空间分配给弹性项目,但fr单位将容器中的自由空间分配给行/列。
从规范中可以看到:

7.2.3. Flexible Lengths: the fr unit

可伸缩长度或<flex>是具有fr单位的尺寸,它代表网格容器中可用空间的一部分。

(请注意,flex-grow应用于弹性项目,而fr长度应用于网格容器。)
因此,在您的网格中,有三行:
  1. 第一行是标题。您希望内容设置其高度。因此,其高度设置为auto

  2. 最后一行是页脚。您希望内容设置其高度。因此,其高度设置为auto

  3. 中间行包含navmain元素。您希望此行占用所有剩余的垂直空间。因此,其高度设置为1fr

.ctnr {
  display: grid;
  grid-template-rows: auto 1fr auto;  /* key rule */
  grid-template-columns: 1fr 1fr;
  height: 100vh;
  grid-template-areas: "header header" 
                         "nav main" 
                       "footer footer";
}

header {
  grid-area: header;
  background: turquoise;
}

nav {
  grid-area: nav;
  background: grey;
}

main {
  grid-area: main;
  background: orange;
}

footer {
  grid-area: footer;
  background: yellow;
}

body {
  margin: 0;
}
<div class="ctnr">
  <header>header</header>
  <nav>nav</nav>
  <main>main</main>
  <footer>footer</footer>
</div>

jsFiddle演示


1
除了接受的答案之外,根据我的情况,有时候页面上会有一个
元素,以及总是有
元素,它们按顺序排列在一起;
应该始终被拉伸(即flex-grow: 1,但是对于grid布局)。
我在父元素上添加了grid-template-rows: auto 1fr auto;。当这三个元素都存在时,这个方法是有效的,但是当
缺失时,它就不起作用了。我通过添加以下内容来解决这个问题:
修复方法: 在父元素上添加grid-template-rows: auto 1fr auto; 在
上添加grid-rows-end: span 2。
解释: <main>始终占据2行。 grid-template-rows是一个无限行的模式,因此第1-3行是auto 1fr auto,第4-6行也是如此,第7-9行,...
当页面上有3个元素时,<header>将占据第一行,值为auto<main>将占据第2和第3行,值为1fr auto<footer>将从第4行开始,这是一个包含auto的新模式的起点。
当只有2个元素(没有<header>)时,<main>将占据第1和第2行,即auto 1fr<footer>将占据第3行,包含auto

有头部:

html,
body {
  height: 100%;
  margin: 0;
}

body {
  display: grid;
  grid-template-rows: auto 1fr auto;
  height: 100%;
}

main {
  grid-row-end: span 2;
}

header,
footer {
  background-color: hotpink;
}
<header>header</header>
<main>main</main>
<footer>footer</footer>

没有标题:

html,
body {
  height: 100%;
  margin: 0;
}

body {
  display: grid;
  grid-template-rows: auto 1fr auto;
  height: 100%;
}

main {
  grid-row-end: span 2;
}

header,
footer {
  background-color: hotpink;
}
<main>main</main>
<footer>footer</footer>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接