I'm trying to build a web layout with a title bar, a nav header, a footer and a main content area in the middle (split in two for a sidebar and main view).
I intend to use CSS Grid layout for it. My current code manages it all, except: The main content (and sidebar) adjust to its content. And that's not what I want.
How can I make that 3rd grid row fill all remaining vertical space?
* {
box-sizing: border-box;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-template-rows: min-content min-content auto min-content;
grid-gap: 10px;
grid-template-areas: "header header" "nav nav" "sidebar main" "footer footer";
}
.title {
grid-area: header;
background-color: #1BC336;
}
.navigation {
grid-area: nav;
background-color: #C3A21B;
}
.sidebar {
grid-area: sidebar;
background-color: gold;
overflow: auto;
}
.main {
grid-area: main;
background-color: #1BC3B9;
overflow: auto;
}
.footer {
grid-area: footer;
background-color: #5C1BC3;
}
<div class="grid">
<div class="title">
<h3>Title Bar</h1>
</div>
<div class="navigation">Navbar</div>
<div class="sidebar">Sidebar:<br>Info-type stuff about what's currently being shown in main</div>
<div class="footer">Footer</div>
<div class="main">
<h1>Main content</h2><br>Should occupy all the remaining space. <br>Test<br>Test<br>Test<br>Test<br>Test</div>
</div>
CSS grid layout is one of the strongest layout of CSS. The grid layout is 2-D which means it can handle both rows and columns, unlike flexbox which is 1-D. To align objects apply CSS to the parent element which becomes the grid container and the element’s child which becomes the items in the grid.
The grid layout is 2-D which means it can handle both rows and columns, unlike flexbox which is 1-D. To align objects apply CSS to the parent element which becomes the grid container and the element’s child which becomes the items in the grid. Use the align-content property of CSS grids to vertically align objects.
CSS line-height Property: In this method, we will set the line-height of list items which will ultimately increases or decrease the vertical spacing of list items. CSS margin-top Property: We will apply margin-top property that will set line-height of list items which will ultimately increases or decrease the vertical spacing of list items.
This is because unless the container (for which you have given display: grid) has a set height, it will take only as much space as its contents. So when you give height there is available space now to fill into. See demo below:
Solution
Set grid height to the viewport height - add height: 100vh
to the .grid
and reset the default browser body
margin to zero.
This is because unless the container (for which you have given display: grid
) has a set height
, it will take only as much space as its contents. So when you give height there is available space now to fill into. See demo below:
* {
box-sizing: border-box;
}
body { /* ADDED */
margin: 0;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-template-rows: min-content min-content auto min-content;
grid-gap: 10px;
grid-template-areas: "header header" "nav nav" "sidebar main" "footer footer";
height: 100vh; /* ADDED */
}
.title {
grid-area: header;
background-color: #1BC336;
}
.navigation {
grid-area: nav;
background-color: #C3A21B;
}
.sidebar {
grid-area: sidebar;
background-color: gold;
overflow: auto;
}
.main {
grid-area: main;
background-color: #1BC3B9;
overflow: auto;
}
.footer {
grid-area: footer;
background-color: #5C1BC3;
}
<div class="grid">
<div class="title">
<h3>Title Bar</h1>
</div>
<div class="navigation">Navbar</div>
<div class="sidebar">Sidebar:<br>Info-type stuff about what's currently being shown in main</div>
<div class="footer">Footer</div>
<div class="main">
<h1>Main content</h2><br>Should occupy all the remaining space. <br>Test<br>Test<br>Test<br>Test<br>Test</div>
</div>
How can I make that 3rd grid row fill all remaining vertical space?
In your layout, there is no remaining vertical space. Since your container doesn't have a defined height, its height is based on the height of the content. So there's no extra space to distribute.
However, if your container had, let's say, the height of the viewport...
.grid { height: 100vh }
... then you could get the sidebar and main content (collectively, the third row) to take all remaining height with:
.grid { grid-template-rows: min-content min-content 1fr min-content; }
instead of
.grid { grid-template-rows: min-content min-content auto min-content; }
* {
box-sizing: border-box;
}
.grid {
height: 100vh;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-template-rows: min-content min-content 1fr min-content;
grid-gap: 10px;
grid-template-areas: "header header"
"nav nav"
"sidebar main"
"footer footer";
}
.title {
grid-area: header;
background-color: #1BC336;
}
.navigation {
grid-area: nav;
background-color: #C3A21B;
}
.sidebar {
grid-area: sidebar;
background-color: gold;
overflow: auto;
}
.main {
grid-area: main;
background-color: #1BC3B9;
overflow: auto;
}
.footer {
grid-area: footer;
background-color: #5C1BC3;
}
body {
margin: 0;
}
<div class="grid">
<div class="title">
<h1>Title Bar</h1>
</div>
<div class="navigation">Navbar</div>
<div class="sidebar">Sidebar:
<br>Info-type stuff about what's currently being shown in main</div>
<div class="footer">Footer</div>
<div class="main">
<h2>Main content</h2>
<br>Should occupy all the remaining space.
</div>
</div>
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