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

xzlaal3s  于 2023-03-05  发布在  其他
关注(0)|答案(4)|浏览(97)

这是我第一次使用CSS Grid Layouts,它们非常棒,但是现在,我很难控制我的一个网格单元。
我想要的是有一个元素占用现有的空闲空间并且 * 不再 *,当内容变得太大时滚动。我的理解是,1fr的网格大小在计算完所有其他内容后会占用相同数量的可用空间。我尝试了各种大小,如minmax(auto, 1fr),但没有效果-1fr似乎会扩展以适应内容,这不是我想要的。设置像100px这样的最大大小size也不好,因为我希望大小由网格中的其他元素确定。
下面是一个例子:

.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>

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

gopyfrb3

gopyfrb31#

height:0 + min-height:100%应在其网格单元格高度(由同级内容定义)内包含一个元素

.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;
  /* here the rules to contain the element to its cell's height */
  min-height:100%;
  height:0;
  overflow-y: auto;
  /* end */
}

.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
    • 在任何地方都不再工作**参见上一个代码段。

你可以使用max-height:100%;min-height来留下足够的高度来显示一个合适的滚动条。**(firefox可以,chrome暂时不行)***
一个二个一个一个
作为一种变通方法,您还可以在absolute位置使用一个额外的 Package 器,将其从流中取出,并将其大小调整为行的高度:
(两种情况都需要最小高度,以便在需要时正确显示滚动条)*

.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>
8wigbo56

8wigbo562#

还有一个更优雅的解决方案,它使用viewport高度单位(vh),只需将100vh应用于容器:

.container {
  display: grid;
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 1fr 1fr;
  height: 100vh; /* <- does the trick */
}

.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;
}

body {
  margin: 0; /* fixes stackoverflow's markup */
}
<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>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus tristique felis eros, et luctus turpis pellentesque nec. Nunc gravida est quis vestibulum tristique. Maecenas consectetur cursus pulvinar. Aenean quis diam sollicitudin nisi ullamcorper consectetur. Nullam dapibus eleifend sollicitudin. Donec ut pulvinar erat, quis suscipit urna. Donec at turpis nunc. Sed diam lectus, tincidunt vel tellus eu, consectetur rhoncus urna. Fusce tempus lectus tellus, sagittis laoreet arcu sagittis vitae. Phasellus varius orci accumsan orci vulputate semper. Maecenas mauris tortor, congue sit amet volutpat pretium, tincidunt et ligula. Donec convallis bibendum nunc at gravida. Pellentesque suscipit, nisl nec commodo tincidunt, metus nibh posuere diam, et finibus nulla mauris scelerisque sem. Maecenas fringilla ullamcorper consectetur.

Nullam non purus vitae nisl scelerisque molestie at et nibh. In hac habitasse platea dictumst. Interdum et malesuada fames ac ante ipsum primis in faucibus. Vestibulum bibendum mattis dignissim. Praesent rutrum ultrices mauris, in maximus orci suscipit iaculis. Ut non neque feugiat, vestibulum massa sed, malesuada nulla. Phasellus eu vehicula odio. Proin vulputate, purus ac posuere pharetra, velit ipsum sollicitudin tellus, ut fermentum sapien risus eu lorem. Nullam viverra mollis finibus. Curabitur cursus lobortis dapibus. Cras aliquet dignissim diam, eu consectetur risus pretium a.

Phasellus consectetur vel tellus et dignissim. Quisque sit amet porta sem, et sagittis sem. Vestibulum blandit tellus enim, sed convallis lectus semper eget. Nunc varius dignissim nunc. Ut ac fringilla justo. Aenean non ex lacus. Mauris pretium egestas facilisis.

Fusce imperdiet turpis vitae tortor tristique, vitae pulvinar erat cursus. Aliquam blandit justo rutrum, efficitur leo vitae, fringilla enim. Cras facilisis dapibus mattis. Duis quis accumsan ipsum. Curabitur consectetur nisi vel mauris tincidunt, sed finibus nisi faucibus. Curabitur efficitur nulla at turpis vehicula congue. Aenean quis nulla id massa elementum commodo quis ut risus. Aliquam congue metus vitae mi dictum aliquet. Nulla facilisi. Donec auctor nisl non turpis scelerisque, ut vestibulum mauris malesuada. Mauris vulputate ut mi vitae congue. Nam ac nulla in neque semper laoreet at in metus.

Cras bibendum, magna ut convallis consectetur, lacus nunc luctus metus, a faucibus quam leo et dui. Nam non sagittis lacus. In leo dui, euismod a tellus eu, volutpat cursus libero. Praesent suscipit mollis turpis, eu imperdiet lorem imperdiet in. Suspendisse potenti. Ut bibendum semper ante, at blandit enim feugiat ut. Nullam eu vehicula lorem. Curabitur maximus ipsum ex, eget mattis urna consectetur id.</div>
  <div class="footer">column footer</div>
</div>
olqngx59

olqngx593#

在@G-Cyr的解决方案上添加。要使max-height工作,至少要有一个绝对定位的元素。将container设置为绝对定位。

.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>
xn1cxnb4

xn1cxnb44#

如果你在problem-child中定义了另一个网格,那么它同样不能正确渲染。你必须将overflow: auto属性从任何父网格下推到子网格。检查给定的codepen:

body {
  height: 100vh;  
  display: grid;
  grid-template-rows: 30px 1fr 20px;
  margin: 0;
}
.header {
  background: green;
}
.footer {
  background: magenta;
}
.page {
  overflow: auto;
}
.container{
  height: 100%;
  display: grid;
  grid-template-rows: 30px 1fr 1fr 30px;
}

.fill-content {
  background: red;
  overflow: auto;
}

.fix-content {
  background: yellow;  
}

.large {
  background: blue;
  width: 100%;
  height: 150px;
}
<div class="header">Page HEader
</div>
<div class="page"> 
<div class="container">
  <div class="fix-content"></div>
  <div class="fill-content">
    <div class="large">fill content 1 by vertical space or scroll it (red layer is filled, blue makes it scrolling)</div>
  </div>
  <div class="fill-content">
    <div class="large">fill content 2 by vertical space or scroll it (red layer is filled, blue makes it scrolling)</div>
  </div>
  <div class="fix-content"></div>
</div>
</div>
<div class="footer">Page Footer</div>

相关问题