I have an element with grid display which has 3 columns - SectionOne
, SectionTwo
, SectionThree
. Column in the middle is also a grid which contains 3 rows - SectionTwoTop
, SectionTwoCenter
, SectionTwoBottom
. I want:
.content
to take up only space available in the viewport (so it wouldn't cause the page to overflow).- Elements
SectionOne
,SectionTwoCenter
, andSectionThree
to overflow if content within them does not fit into a viewport. .footer
to be visible at the bottom.
Now, the problem is not so much the .content
itself but the current layout where I want to add these changes. I just cannot achieve the result that I want within that layout. Anyway, I would prefer only to make changes to .content
and its child elements and not to the surrounding layout.
Here is a relevant code:
index.css
.container-blueprint {
display: grid;
grid-template-columns: min-content 1fr min-content;
grid-template-rows: 1fr;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
"SectionOne SectionTwo SectionThree"
"SectionOne SectionTwo SectionThree"
"SectionOne SectionTwo SectionThree";
}
.SectionOne {
overflow-y: auto;
grid-area: SectionOne;
width: 300px;
}
.SectionTwo {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: min-content 1fr min-content;
gap: 0px 0px;
grid-auto-flow: row;
grid-template-areas:
"SectionTwoTop SectionTwoTop SectionTwoTop"
"SectionTwoCenter SectionTwoCenter SectionTwoCenter"
"SectionTwoBottom SectionTwoBottom SectionTwoBottom";
grid-area: SectionTwo;
}
.SectionThree {
overflow-y: auto;
grid-area: SectionThree;
width: 100px;
}
.SectionTwoTop {
height: 100px;
grid-area: SectionTwoTop;
}
.SectionTwoCenter {
overflow-y: auto;
grid-area: SectionTwoCenter;
}
.SectionTwoBottom {
height: 100px;
grid-area: SectionTwoBottom;
}
/* Other styles. */
html,
body {
height: 100%;
margin: 0;
box-sizing: border-box;
}
body {
display: grid;
min-height: 100vh;
grid-template-columns: auto 1fr;
grid-template-rows: min-content min-content 1fr min-content;
}
.container-blueprint * {
border: 1px solid red;
position: relative;
}
.header {
grid-area: 1/1/2/3;
}
.nav {
grid-area: 2/2/3/3;
}
.sidebar {
grid-area: 2/1/4/2;
}
.content {
grid-area: 3/2/4/3;
}
.footer {
grid-area: 4/1/5/3;
}
index.html
<!DOCTYPE html>
<html>
<head>
<link href="index.css" rel="stylesheet" />
</head>
<body>
<div class="header">[HEADER]</div>
<div class="nav">[NAV]</div>
<div class="sidebar">[SIDEBAR]</div>
<!-- BEGIN -->
<div class="content">
<div class="container-blueprint">
<div class="SectionOne">[SECTION ONE]</div>
<div class="SectionTwo">
<div class="SectionTwoTop">[SECTION TWO TOP]</div>
<div class="SectionTwoCenter">[SECTION TWO CENTER]</div>
<div class="SectionTwoBottom">[SECTION TWO BOTTOM]</div>
</div>
<div class="SectionThree">[SECTION THREE]</div>
</div>
</div>
<!-- END -->
<div class="footer">[FOOTER]</div>
<script src="index.js"></script>
</body>
</html>
Here is a link to an interactive demo:
I can achieve what I want by using calc(100vh - <height of the top content>)
on the relevant elements but I do not want to use this approach because I may not know height of the elements and it feels like a bad approach overall (for example, after height in top elements changes, I need to update calc()
function again to prevent page overflow or gap below). I tried various approaches with flex
and table
display options but I cannot for the life of me get the result that I want.