I've been having problems with implementing a nested grid structure.
This is a simplified example. As you can see the nested structure gives the height for the outer structure, thus growing outside the body.
What I'd like to achieve is to make the .content__inner
element, and only that element scrollable. Everything else should be inside the viewport. How can I achieve that?
Edit 1: Just to clarify, I'm using 100vh on the body, but don't want to set it on the container. The container should have the height of its parent, whatever it is.
body {
display: block;
height: 100vh;
width: 100%;
background-color: white;
margin: 0;
}
.container {
max-height: 100%;
display: grid;
grid-template-areas: "header header" "side content" "footer footer";
grid-template-columns: 50px auto;
grid-template-rows: min-content minmax(min-content, max-content) min-content;
}
.header {
grid-area: header;
background-color: rgba(255, 255, 0, 0.3);
}
.side {
grid-area: side;
background-color: rgba(0, 255, 0, 0.3);
}
.content {
grid-area: content;
background-color: rgba(0, 0, 255, 0.3);
}
.overflow {
overflow: auto;
}
.content-item {
height: 20px;
margin-bottom: 5px;
background-color: white;
}
.footer {
grid-area: footer;
background-color: rgba(255, 0, 255, 0.3);
}
<div class="container">
<div class="header">header</div>
<div class="side">side</div>
<div class="content">
<div class="container container__inner">
<div class="header header__inner">header</div>
<div class="side side__inner">side</div>
<div class="content content__inner overflow">
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
</div>
<div class="footer footer__inner">footer</div>
</div>
</div>
<div class="footer">footer</div>
</div>
To allow the grid to auto-size it's height to fit rows, set grid property domLayout='autoHeight' .
Building a Responsive Grid-View First ensure that all HTML elements have the box-sizing property set to border-box . This makes sure that the padding and border are included in the total width and height of the elements. Read more about the box-sizing property in our CSS Box Sizing chapter.
Change the row height to fit the contents Select the row or rows that you want to change. On the Home tab, in the Cells group, click Format. Under Cell Size, click AutoFit Row Height.
Auto-placement by column In this case grid will add items in rows that you have defined using grid-template-rows . When it fills up a column it will move onto the next explicit column, or create a new column track in the implicit grid. As with implicit row tracks, these column tracks will be auto sized.
The problem is easy to describe, but may not have a simple solution (depending on your requirements).
The problem is actually clear to see in the title itself:
Css grid auto sized row content with overflow
Auto-sized elements cannot overflow. They are auto sized. This means the element shrinks and expands based on its content size, never having a need to overflow.
There has to be something that sets a fixed length on the container. A boundary that can be crossed, thus triggering an overflow condition.
From MDN:*
In order for
overflow
to have an effect, the block-level container must have either a set height (height
ormax-height
) orwhite-space
set tonowrap
.
Your row heights are insufficient to trigger an overflow:
grid-template-rows: min-content minmax(min-content, max-content) min-content
But something like this would work:
grid-template-rows: 10% 80% 10%
Unfortunately, the code above only works in Chrome. For the layout to also work in Firefox and Edge, do this:
grid-template-rows: 10% minmax(0, 80%) 10%
body {
display: block;
height: 100vh;
width: 100%;
background-color: white;
margin: 0;
}
.container {
max-height: 100%;
display: grid;
grid-template-areas: "header header" "side content" "footer footer";
grid-template-columns: 50px auto;
grid-template-rows: 10% minmax(0, 80%) 10%; /* adjustment */
}
.header {
grid-area: header;
background-color: rgba(255, 255, 0, 0.3);
}
.side {
grid-area: side;
background-color: rgba(0, 255, 0, 0.3);
}
.content {
grid-area: content;
background-color: rgba(0, 0, 255, 0.3);
}
.overflow {
overflow: auto;
}
.content-item {
height: 20px;
margin-bottom: 5px;
background-color: white;
}
.footer {
grid-area: footer;
background-color: rgba(255, 0, 255, 0.3);
}
<div class="container">
<div class="header">header</div>
<div class="side">side</div>
<div class="content">
<div class="container container__inner">
<div class="header header__inner">header</div>
<div class="side side__inner">side</div>
<div class="content content__inner overflow">
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
<div class="content-item"></div>
</div>
<div class="footer footer__inner">footer</div>
</div>
</div>
<div class="footer">footer</div>
</div>
Basically, you need to find some way to set a fixed height limit on the overflow row for the scrollbar to function.
For an explanation of the browser differences described above see these posts:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With