Sticky navigation and fullscreen header

So I was making this document layout for a website that is kind of like a report.

Layout

  1. Navigation
  2. Header
  3. Aside | Main

Navigation is containing links to several pages but only importent thing here is that it has position: sticky.

Header is a header element containing a picture and content div. I wanted to make sure that the picture or img tag never is bigger than 100vh (max viewport height). As you would get a header that is as big as your screen (above the fold 🤢) but never bigger.

Because you can do something like this with grid I made the following css and js. Yes js a bit because of potential growing .navigation issues.

Example code

<nav class="navigation">...</nav>  
<header class="frontpage-header ">

<picture>
<img>
</picture>

<div class="content">
<hgroup class="heading-group">
<p class="header-label">What comes around?</p>
<h1 class="header-title">A fantastic title which is rather long...</h1>
</hgroup>
</div>

</header>
.navigation {
position: sticky;
top: 0;
}
.header {
display: grid;
grid-template-areas: 'media' 'content';

grid-template-rows: minmax(0, 1fr) auto;
max-height: calc(100vh - var(--nav-height, 10rem));
overflow: hidden;

picture {
grid-area: media;
width: 100%;
height: 100%;

img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.content {
grid-area: content;
}
}

Now the content part of this header can grow as much as it needs. For example if the title is longer and spans several lines.

And for the --nav-height custom prop, I use a bit of javascript (ts) in other to make sure that is always correct. For example if browser resizes or there are more items that make the navigation bigger/higher.

function setNavHeight(nav: Element): void {
document.documentElement.style.setProperty("--nav-height", `${nav.getBoundingClientRect().height}px`);
}

export default function navigationInit(): void {
const navigation = document.querySelector(".navigation");
if (!navigation) return;

setNavHeight(navigation);

const resizeObserver = new ResizeObserver(() => {
setNavHeight(navigation);
});
resizeObserver.observe(navigation);
}

With this I have a rather fancy header that is responsive and will work in most situations.

coming soon

I'll make a codepen to showcase this post soon!