Goal: sticky nav bar at top, followed by grid where last row of the grid maintains its natural height, but is at the bottom of the window if there's insufficient content to push it off screen.
Problem: I'm having issues getting my grid to be 100% of the height of the content, which is messing up my sticky nav bar (at least I think this is the issue). My content is coming from a headless CMS, and HTML is generated via NextJS. A page generally looks like this:
<html>
<body>
<div id="__next">
<header></header> // should be sticky
<div> // wrapper, which I'm making a grid
Somewhat arbitrary content from the CMS...
<footer>Comes from the CMS also</footer>
</div>
</div>
</body>
</html>
Styling the header like so basically worked:
header {
position: sticky;
top: 0px;
left: 0px;
width: 100%;
}
However, when I got around to creating custom error pages, I realised that if there was insufficient content, the footer inside my grid wasn't at the bottom of the page. After some googling and experimenting, the solution seemed to be to make sure that the html and body both had height: 100%; min-height: 100vh;, and that, because there was only 1 row in the grid before the footer, I could do grid-template-rows: 1fr auto;, so the the first row would expand to fill the available space, and the footer would shrink to its proper size, but get pushed to the bottom.
So far, so good — that worked on the pages with little/no content. But, now I have a problem with regular pages (i.e., pages with more than one row, and/or sufficient content to be taller than vh.
As you can see in this snippet, the sticky nav bar is sticky for a while, but then stops being sticky. This appears to me to be because the grid container is not expanding to the height of all of its content.
html {
height: 100%;
}
body {
height: 100%;
}
#__next {
min-height: 100vw;
height: 100%;
}
header {
position: sticky;
top: 0px;
left: 0px;
width: 100%;
}
footer {
padding-left: calc(((100vw - 80rem) / 2) + (80rem / 12));
padding-right: calc(((100vw - 80rem) / 2) + (80rem / 12));
width: 100%;
grid-column-start: 2;
grid-column-end: 12;
/* appearance only */
padding: 6rem 0;
background-color: #121212;
color: #fff;
}
.wrapper {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
/* grid-auto-rows: 1fr; */
max-width: 80rem;
min-height: 100%;
height: 100%;
margin: 0 auto;
}
.item-1 {
grid-column-start: 2;
grid-column-end: 7;
align-self: flex-end;
}
.item-2 {
grid-column-start: 2;
grid-column-end: 7;
align-self: flex-start;
}
.item-3 {
grid-row: span 2 / span 2;
grid-row-start: 1;
grid-column-start: 7;
grid-column-end: 12;
height: 787px;
background-color: #dedede;
}
.item-4 {
grid-column-start: 2;
grid-column-end: 12;
}
<html>
<body>
<div id="__next">
<header>
<nav><span>I'm in the header, and should stick. Scroll down to see it work for a while ... and then stop.</span></nav>
</header>
<div class="wrapper">
<div class="item-1">
<h1>I'm at the bottom of my container.</h1>
</div>
<div class="item-2">
<p>I flow nicely after that, because I'm at the top</p>
</div>
<div class="item-3">I'm an image</div>
<section class="item-4">
<p>I'm some more content.</p>
<div style="height: 300px">Just taking up space</div>
</section>
<footer>I'm fancy, I'm a footer.</footer>
</div>
</div>
</body>
</html>
I tried grid-auto-rows: 1fr;, grid-template-rows: 1fr auto;, and grid-auto-rows: auto;, but to no avail.
How do I achieve my desired goal (i.e., footer inside grid at bottom of window when insufficient content; sticky nav bar, outside of grid)?
Edit: NB: Since I'm writing the NextJS, and control the CMS templates, I can move the footer out of the grid, if that helps at all.