【问题标题】:How to make CSS Grid items take up remaining space?如何让 CSS Grid 项目占用剩余空间?
【发布时间】:2018-01-29 15:39:24
【问题描述】:

我有一张使用 CSS 网格布局构建的卡片。左边可能有一张图片,右上方可能有一些文字,右下方可能有一个按钮或链接。

在下面的代码中,如何让绿色区域占用尽可能多的空间,同时让蓝色区域占用尽可能少的空间?

绿色应尽可能将蓝色区域向下推。

https://jsfiddle.net/9nxpvs5m/

.grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-areas:
    "one two"
    "one three"
}

.one {
  background: red;
  grid-area: one;
  padding: 50px 0;
}

.two {
  background: green;
  grid-area: two;
}

.three {
  background: blue;
  grid-area: three;
}
<div class="grid">
  <div class="one">
    One
  </div>
  <div class="two">
    Two
  </div>
  <div class="three">
    Three
  </div>
</div>

【问题讨论】:

  • 不是按原样回答问题,但可能仍然有价值:我会用 flexbox 和 .two.three 周围的额外容器来做这件事:jsfiddle.net/9nxpvs5m/2跨度>

标签: html css grid css-grid


【解决方案1】:

grid-template-rows: 1fr min-content; 添加到您的.grid 将得到您所追求的:)。

.grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: 1fr min-content;
  grid-template-areas:
    "one two"
    "one three"
}

.one {
  background: red;
  grid-area: one;
  padding: 50px 0;
}

.two {
  background: green;
  grid-area: two;
}

.three {
  background: blue;
  grid-area: three;
}
<div class="grid">
  <div class="one">
    One
  </div>
  <div class="two">
    Two
  </div>
  <div class="three">
    Three
  </div>
</div>

Jens 编辑:为了获得更好的浏览器支持,可以改用:grid-template-rows: 1fr auto;,至少在这种情况下是这样。

【讨论】:

  • 我在使用单列四行网格时遇到了类似的问题。使用grid-template-rows: auto auto auto 1fr;,它现在扩展最后一行以填充页面的其余部分。这是我的目标——感谢您的提示。
【解决方案2】:

网格是一系列相交的行和列。

您希望第二列中的两个项目根据其内容高度自动调整其行高。

这不是网格的工作方式。对第二列行高的此类更改也会影响第一列。

如果你必须使用 CSS Grid,那么我要做的就是给容器,比如说 12 行,然后根据需要让项目跨行。

.grid {
  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-template-rows: repeat(12, 15px);
}

.one {
  grid-row: 1 / -1;
  background: red;
}

.two {
  grid-row: span 10;
  background: lightgreen;
}

.three {
  grid-row: span 2;
  background: aqua;
}

.grid > div {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="grid">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>

否则,您可以尝试使用 flexbox 解决方案。

.grid {
  display: flex;
  flex-flow: column wrap;
  height: 200px;
}

.one {
  flex: 0 0 100%;
  width: 30%;
  background: red;
}

.two {
  flex: 1 0 1px;
  width: 70%;
  background: lightgreen;
}

.three {
  background: aqua;
}

.grid>div {
  display: flex;
  align-items: center;
  justify-content: center;
}
<div class="grid">
  <div class="one">One</div>
  <div class="two">Two</div>
  <div class="three">Three</div>
</div>

【讨论】:

  • 我曾考虑过 min-content 方法,但该值对浏览器的支持较弱。当我测试它时,它在 Safari 和 Firefox 中不起作用。
【解决方案3】:

当使用网格时,您使用了网格模板区域,并且偶然给特定区域指定了宽度,您会自动留下一个空间网格。 在这种情况下,让 grid-template-columns 为 min-content 或 max-content,以便它自动调整其位置。

【讨论】:

    【解决方案4】:

    一种可能的方法是将twothree 组合在一起,并使用flexbox

    .grid {
      display: grid;
      grid-template-columns: 1fr 3fr;
      grid-template-areas: "one two"
    }
    
    .one {
      background: red;
      grid-area: one;
      padding: 50px 0;
    }
    
    .wrap {
      grid-area: two;
      display: flex;
      flex-direction: column;
    }
    
    .two {
      background: green;
      flex: 1;
    }
    
    .three {
      background: blue;
    }
    <div class="grid">
      <div class="one">
        One
      </div>
      <div class="wrap">
    
        <div class="two">
          Two
        </div>
        <div class="three">
          Three
        </div>
      </div>
    </div>

    【讨论】:

    • 正是我的想法。这些天来,Flexbox 确实是我的首选解决方案。然而,它是一个可怜的 flexbox,实际上 flex 不足以让这个简单的布局在没有 .two.three 周围的额外容器的情况下运行 - 或者是有办法吗?
    • @domsson 不是我能想到的:)
    • 我认为这是一种解决方法,所以我会等待一段时间,然后再接受它作为答案。仅网格解决方案(如果存在)将被接受为答案。
    【解决方案5】:

    绝对不是最优雅的解决方案,也可能不是最佳实践,但您总是可以添加更多行

    "one two"
    

    在你拥有的部分之前

    "one three"
    

    所以它最终看起来像

    .grid {
      display: grid;
      grid-template-columns: 1fr 3fr;
      grid-template-areas:
        "one two"
        "one two"
        "one two"
        "one three"
    }
    

    再一次,很确定这只是一种变通方法,并且有更好的解决方案......但公平地说,这确实有效。

    【讨论】:

      【解决方案6】:

      只需在要填充网格的项目的 CSS 类中使用 width: 100%height: 100%。如果您不希望网格容器内的网格项增长超过某个大小,请加入 max-width 属性和 max-height 属性。

      【讨论】: