CSS网格:使用可用空间的内容,但更大时滚动

时间:2022-07-27 15:26:05

I've been working with CSS Grid Layouts for the first time and they're awesome. Right now, however, I'm having trouble keeping one of my grid cells under control.

我第一次使用CSS Grid Layouts并且它们非常棒。但是,现在我无法控制我的一个网格单元。

What I want is to have an element that takes up the existing free space and no more, scrolling when the content gets too big. My understanding is that a grid size of 1fr takes up a uniform amount of the available space after everything else is calculated. I've tried various sizes such as minmax(auto, 1fr) but to no avail - 1fr seems to expand to fit the content which is not what I want. Setting a maximum size size like 100px is also no good because I want the size to be determined by other elements in the grid.

我想要的是拥有一个占用现有空闲空间的元素,而不是更多,当内容变得太大时滚动。我的理解是,在计算完所有其他内容后,1fr的网格大小会占用可用空间的均匀数量。我尝试了各种尺寸,如minmax(auto,1fr),但无济于事--1fr似乎扩展到适合我不想要的内容。设置最大尺寸大小如100px也不好,因为我希望大小由网格中的其他元素决定。

Here's the example:

这是一个例子:

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

.container>div {
  border: 1px solid blue;
  border-radius: 5px;
}

.left {
  grid-column: 1;
  grid-row: 1/4;
}

.header {
  grid-column: 2;
  grid-row: 1;
}

.problem-child {
  grid-column: 2;
  grid-row: 2;
  overflow-y: scroll;
}

.footer {
  grid-column: 2;
  grid-row: 3;
}
<div class="container">
  <div class="left">left<br>I don't want this one to scroll<br>this should<br>determine<br>the height of the whole grid container</div>
  <div class="header">column header</div>
  <div class="problem-child">problem child:<br>I<br>want<br>this<br>to<br>scroll<br>rather<br>than<br>making<br>everything<br>tall</div>
  <div class="footer">column footer</div>
</div>

What grid declaration (if any) can I use to let the "problem child" scroll on overflow rather than expanding?

我可以使用什么网格声明(如果有的话)让“问题孩子”滚动溢出而不是扩展?

2 个解决方案

#1


10  

You can use max-height:100%; and also min-height to leave enough heights to show a proper scrollbar.(firefox will do, chrome will not at this time)

你可以使用max-height:100%;并且最小高度留下足够的高度来显示正确的滚动条。(firefox会这样做,此时不会镀铬)

.container {
  display: grid;
  grid-template-rows: auto minmax(1fr, 25vh) auto;
  grid-template-columns: 1fr 1fr;
}

.container>div {
  border: 1px solid blue;
  border-radius: 5px;
}

.left {
  grid-column: 1;
  grid-row: 1/4;
}

.header {
  grid-column: 2;
  grid-row: 1;
}

.problem-child {
  grid-column: 2;
  grid-row: 2;
  min-height:4em;
  max-height:100%;
  overflow-y: auto;
}

.footer {
  grid-column: 2;
  grid-row: 3;
}
<div class="container">
  <div class="left">left<br>I don't want this one to scroll<br>this should<br>determine<br>the height of the whole grid container</div>
  <div class="header">column header</div>
  <div class="problem-child">problem child:<br>I<br>want<br>this<br>to<br>scroll<br>rather<br>than<br>making<br>everything<br>tall</div>
  <div class="footer">column footer</div>
</div>


As a work around, you can also use an extra wrapper in absolute position to take it off the flow and size it to the row's height: (both cases require a min-height to show properly the scrollbar when needed)

作为一种解决方法,您还可以在绝对位置使用额外的包装器将其从流量中取出并将其调整到行的高度:(两种情况都需要最小高度以在需要时正确显示滚动条)

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

.container>div {
  border: 1px solid blue;
  border-radius: 5px;
}

.left {
  grid-column: 1;
  grid-row: 1/4;
}

.header {
  grid-column: 2;
  grid-row: 1;
}

.problem-child {
  grid-column: 2;
  grid-row: 2;
  position:relative;
  min-height:4em;
  }

.problem-child >div {
  position:absolute;
  top:0;
  left:0;
  right:0;
  max-height:100%;
  overflow:auto ;
}

.footer {
  grid-column: 2;
  grid-row: 3;
}
<div class="container">
  <div class="left">left<br>I don't want this one to scroll<br>this should<br>determine<br>the height of the whole grid container</div>
  <div class="header">column header</div>
  <div class="problem-child">
    <div>problem child:<br>I<br>want<br>this<br>to<br>scroll<br>rather<br>than<br>making<br>everything<br>tall</div>
  </div>
  <div class="footer">column footer</div>
</div>

#2


6  

Adding on top of @G-Cyr's solution. There should be atleast one element absolutely positioned for max-height to work. Set container to be absolutely positioned.

添加@ G-Cyr的解决方案。应该至少有一个元素绝对定位为最大高度工作。将容器设置为绝对定位。

.container {
  display: grid;
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 1fr 1fr;
  height: 100%;
  width: 100%;
  position: absolute;
}

.container>div {
  border: 1px solid blue;
  border-radius: 5px;
}

.left {
  grid-column: 1;
  grid-row: 1/4;
}

.header {
  grid-column: 2;
  grid-row: 1;
}

.problem-child {
  grid-column: 2;
  grid-row: 2;
  max-height: 100%;
  overflow-y: auto;
}

.footer {
  grid-column: 2;
  grid-row: 3;
}
<div class="container">
  <div class="left">left<br>I don't want this one to scroll<br>this should<br>determine<br>the height of the whole grid container</div>
  <div class="header">column header</div>
  <div class="problem-child">problem child:<br>I<br>want<br>this<br>to<br>scroll<br>rather<br>than<br>making<br>everything<br>tall</div>
  <div class="footer">column footer</div>
</div>

#1


10  

You can use max-height:100%; and also min-height to leave enough heights to show a proper scrollbar.(firefox will do, chrome will not at this time)

你可以使用max-height:100%;并且最小高度留下足够的高度来显示正确的滚动条。(firefox会这样做,此时不会镀铬)

.container {
  display: grid;
  grid-template-rows: auto minmax(1fr, 25vh) auto;
  grid-template-columns: 1fr 1fr;
}

.container>div {
  border: 1px solid blue;
  border-radius: 5px;
}

.left {
  grid-column: 1;
  grid-row: 1/4;
}

.header {
  grid-column: 2;
  grid-row: 1;
}

.problem-child {
  grid-column: 2;
  grid-row: 2;
  min-height:4em;
  max-height:100%;
  overflow-y: auto;
}

.footer {
  grid-column: 2;
  grid-row: 3;
}
<div class="container">
  <div class="left">left<br>I don't want this one to scroll<br>this should<br>determine<br>the height of the whole grid container</div>
  <div class="header">column header</div>
  <div class="problem-child">problem child:<br>I<br>want<br>this<br>to<br>scroll<br>rather<br>than<br>making<br>everything<br>tall</div>
  <div class="footer">column footer</div>
</div>


As a work around, you can also use an extra wrapper in absolute position to take it off the flow and size it to the row's height: (both cases require a min-height to show properly the scrollbar when needed)

作为一种解决方法,您还可以在绝对位置使用额外的包装器将其从流量中取出并将其调整到行的高度:(两种情况都需要最小高度以在需要时正确显示滚动条)

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

.container>div {
  border: 1px solid blue;
  border-radius: 5px;
}

.left {
  grid-column: 1;
  grid-row: 1/4;
}

.header {
  grid-column: 2;
  grid-row: 1;
}

.problem-child {
  grid-column: 2;
  grid-row: 2;
  position:relative;
  min-height:4em;
  }

.problem-child >div {
  position:absolute;
  top:0;
  left:0;
  right:0;
  max-height:100%;
  overflow:auto ;
}

.footer {
  grid-column: 2;
  grid-row: 3;
}
<div class="container">
  <div class="left">left<br>I don't want this one to scroll<br>this should<br>determine<br>the height of the whole grid container</div>
  <div class="header">column header</div>
  <div class="problem-child">
    <div>problem child:<br>I<br>want<br>this<br>to<br>scroll<br>rather<br>than<br>making<br>everything<br>tall</div>
  </div>
  <div class="footer">column footer</div>
</div>

#2


6  

Adding on top of @G-Cyr's solution. There should be atleast one element absolutely positioned for max-height to work. Set container to be absolutely positioned.

添加@ G-Cyr的解决方案。应该至少有一个元素绝对定位为最大高度工作。将容器设置为绝对定位。

.container {
  display: grid;
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 1fr 1fr;
  height: 100%;
  width: 100%;
  position: absolute;
}

.container>div {
  border: 1px solid blue;
  border-radius: 5px;
}

.left {
  grid-column: 1;
  grid-row: 1/4;
}

.header {
  grid-column: 2;
  grid-row: 1;
}

.problem-child {
  grid-column: 2;
  grid-row: 2;
  max-height: 100%;
  overflow-y: auto;
}

.footer {
  grid-column: 2;
  grid-row: 3;
}
<div class="container">
  <div class="left">left<br>I don't want this one to scroll<br>this should<br>determine<br>the height of the whole grid container</div>
  <div class="header">column header</div>
  <div class="problem-child">problem child:<br>I<br>want<br>this<br>to<br>scroll<br>rather<br>than<br>making<br>everything<br>tall</div>
  <div class="footer">column footer</div>
</div>