CSS 网格:行未占据全高 space 可用

CSS Grid : row not taking full height space available

我想使用 css 网格(不是 flexbox)实现一个非常简单的布局:

目前我有这个(类似但有一个不需要的空白区域):

我的问题是我的示例代码中缺少哪些部分来实现所需的布局?

这个问题似乎与这个问题非常相似:
还有这个:How do you collapse unused row in a CSS grid?

但是...有点复杂,因为我还有一行

我在最后一行有一个绿色的div,这最后一行需要随着页面高度的增长而增长。
为此,最后一行的行模板设置为 1fr.

我当前的代码

您可以查看下面非常简单的代码片段:

html {
    height: 100%;
}
body {
    height: 100vh;
}
.container {
    display: grid;
    grid-template-columns: 180px 1fr;
    grid-template-rows: min-content auto 1fr;
    height:100%;
}

.red-cube {
    background-color: red;
    width: 100%;
    Height: 180px;
    grid-column: 1;
    grid-row: 1 / 3;
}
h1, h2 {
    margin: 0;
    padding: 0;
}
.blue-title {
    background-color: blue;
    grid-column: 2;
    grid-row: 1;
    height: fit-content;
}
.yellow-div {
    background-color: yellow;
    grid-column: 2;
    grid-row: 2;
    height: 100%;
}
.green-content {
    background-color: green;
    grid-column: 1 / 3;
    grid-row: 3;
    align-self: stretch;
}
<div class="container">
    <div class="red-cube"></div>
    <h1 class="blue-title">Title</h1>
    <div class="yellow-div"><h2>Second line</h2></div>
    <div class="green-content"><p>Some text</p></div>
</div>

或者在 Codepen here.

上玩一下代码片段

接近失败

我测试了将黄色行的grid-template-rows值设置为1fr以消耗剩余的免费space的解决方案。 (我之前提到的Whosebug问题的解答)

即将 grid-template-rows: min-content auto 1fr; 替换为 grid-template-rows: min-content 1fr 1fr;

但这会破坏需要随页面高度增长的绿色div,因为我们将有两行设置为1fr

结论

不知道有没有不切换到flexbox或者不创建多网格布局(重新组织布局)的解决方案

我也不想通过放置类似以下内容来“硬编码”行高: grid-template-rows: 1.25rem auto 1fr;

看起来最简单的解决方案是嵌套网格设置(不要与 subgrid 混淆)。将 .green-content div 移到 .container 网格之外。然后将 body 设置为具有两行的网格 - 第一行的高度为 180px,第二行的高度为 1fr。 180 像素的行将作为 .container 网格的父级。请注意,如果您不想使用整个页面,也可以使用除 body 之外的其他元素作为父网格。下面的代码片段是一个工作示例

html {
    height: 100%;
}

body {
    height: 100vh;
    display: grid;
    grid-template-rows: 180px 1fr;
}

.container {
    display: grid;
    grid-template-columns: 180px 1fr;
    grid-template-rows: max-content 1fr;
}

.red-cube {
    background-color: red;
    width: 100%;
    height: 180px;
    grid-column: 1;
    grid-row: 1 / 3;
 }

h1, h2, p {
    margin: 0;
    padding: 0;
}

.blue-title {
    background-color: blue;
    grid-column: 2;
    grid-row: 1;
    height: fit-content;
 }

 .yellow-div {
    background-color: yellow;
    grid-column: 2;
    grid-row: 2;
    height: 100%;
 }

.green-content {
    background-color: green;
    margin-top: 0;
}
<div class="container">
    <div class="red-cube"></div>
    <h1 class="blue-title">Title</h1>
    <div class="yellow-div"><h2>Second line</h2></div>
</div>
<div class="green-content"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ac accumsan eros. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed dictum in magna eu luctus. Fusce feugiat lectus tortor, eget consectetur augue convallis non. Aliquam massa tortor, fermentum eu nibh non, sollicitudin molestie mi. Ut nec eros sagittis sapien tristique accumsan. Vivamus dapibus, nulla vitae facilisis volutpat, velit odio viverra nisl, non tempor erat mi condimentum velit. Duis posuere sem arcu, venenatis condimentum lorem efficitur eu. Quisque et mi quis lorem pellentesque ultrices. Ut felis lacus, vestibulum sit amet libero non, viverra condimentum turpis. Phasellus massa quam, vestibulum sit amet fermentum molestie, egestas in velit. Donec tristique tempus urna. Nullam pellentesque volutpat mattis. Nunc volutpat orci vel dolor ultrices vestibulum.

Aenean volutpat lacus vitae vehicula semper. Nunc volutpat auctor ligula. Nulla sed augue sem. Vestibulum suscipit ante ac mi viverra, quis feugiat orci posuere. Quisque sit amet tortor luctus, mollis neque a, varius velit. Maecenas sed pulvinar eros, at pretium diam. Duis tellus leo, blandit eget turpis eu, ultricies condimentum dolor. Aliquam erat volutpat. Duis convallis enim lacus, vitae placerat dui dictum convallis. Suspendisse viverra magna vel tellus condimentum, vel pharetra lacus rhoncus. Nam quis mattis elit. Nullam ultricies metus odio, a lobortis quam pharetra sed. Suspendisse vestibulum ullamcorper neque, condimentum euismod ex venenatis ac. Aenean vitae ex eget ligula ultricies condimentum. Donec quis nibh nec massa rutrum dignissim non eget tortor.

Praesent sollicitudin varius diam vel hendrerit. Ut sit amet finibus turpis, sit amet rutrum quam. Sed vestibulum tortor vel quam viverra ullamcorper. Aliquam erat volutpat. Sed gravida, risus vitae dignissim ornare, felis ante vestibulum sapien, nec tempor eros arcu in enim. Nullam suscipit mollis arcu non aliquet. Aenean sit amet nisl dui. In euismod turpis et velit pellentesque fringilla. Ut ut quam lobortis neque egestas pulvinar ac nec ante. Donec tortor odio, posuere eget congue vitae, accumsan eget nisl. Curabitur nunc urna, elementum id erat a, viverra maximus eros. Proin dictum eget ante eget aliquam. Aenean sit amet diam imperdiet, lobortis diam ultricies, dapibus velit.

Morbi neque lectus, cursus in sagittis quis, sollicitudin ac elit. Aenean porta dui in euismod bibendum. Morbi lacus felis, mattis nec feugiat non, laoreet et nibh. Suspendisse mauris arcu, fringilla vitae dolor a, finibus venenatis metus. Etiam justo nunc, eleifend pretium nibh nec, euismod luctus justo. Pellentesque risus leo, congue vel metus a, gravida volutpat arcu. In iaculis sollicitudin tincidunt.

Donec ac leo id nisl malesuada viverra et id libero. Aliquam scelerisque efficitur ipsum a imperdiet. Curabitur porttitor lorem quis orci luctus, at tincidunt leo tempor. Aenean condimentum feugiat sapien, id mattis justo dignissim a. Cras quis odio a quam euismod placerat et in ex. Nulla consequat scelerisque nisl eget faucibus. Mauris eros mauris, ultricies sit amet ex accumsan, pellentesque sagittis tortor. Nam fringilla interdum quam, sed ullamcorper neque egestas id. Proin sed mattis tortor, ac auctor arcu. Cras eu neque mauris. Praesent gravida, libero eget ornare tincidunt, nibh justo consequat lorem, mattis facilisis nibh massa eu urna.</p></div>

这可能不是最优雅的解决方案,但它可以让您免于混乱 calc() 或在 rem 中定义特定高度。

经过大量测试,我找到了一种无需触及 HTML 布局即可实现我想要的结果的方法。

为了强制网格算法消耗第二行可用的空闲 space,目前需要使用 分数 单位的行高(fr).
所以在 CSS 中我添加了一个高度为 0fr 的行(是的,0 分数被认为是有效的并触发网格算法)。

  • 现在 红色方块 () 在第 1 和第 2 行。
  • 蓝色标题 () 在第 1 行。
  • 黄色的sub-title ()在第2&3行(第三行是特殊的0fr行)
  • 绿色文字 ()在第4行。

结果:

代码片段:

html {
    height: 100%;
}
body {
    height: 100vh;
}
.container {
    display: grid;
    grid-template-columns: 180px 1fr;
    grid-template-rows: min-content auto 0fr 1fr;
    height:100%;
}

.red-cube {
    background-color: red;
    width: 100%;
    Height: 180px;
    grid-column: 1;
    grid-row: 1 / 3;
}
h1, h2 {
    margin: 0;
    padding: 0;
}
.blue-title {
    background-color: blue;
    grid-column: 2;
    grid-row: 1;
    height: fit-content;
}
.yellow-div {
    background-color: yellow;
    grid-column: 2;
    grid-row: 2 / 4;
    height: 100%;
}
.green-content {
    background-color: green;
    grid-column: 1 / 3;
    grid-row: 4;
    align-self: stretch;
}
<div class="container">
    <div class="red-cube"></div>
    <h1 class="blue-title">Title</h1>
    <div class="yellow-div"><h2>Second line</h2></div>
    <div class="green-content"><p>Some text</p></div>
</div>

我在 Chrome、Firefox 和 Safari 上测试了这个解决方案,它们都给出了想要的结果;)

你也可以玩这个Codepen版本:https://codepen.io/BSO__/pen/wvrEBWx