Before we start, take an aside to open the Chrome dev tools using the shortcut ctrl + shift + i. Click the icon that looks like a hangman’s gantry with a little phone on the noose, swinging in the breeze. Dark you say? Fine, click on the icon that looks like the truck crane that I’d like in my imaginary F450 steel flatbed, hoisting up a gently used rotary screw compressor for my new sandblasting side-hustle. Better? That icon toggles the device toolbar and lets you select different phones and such from the drop-down at the top of the screen. However, I mostly used “Dimensions: Responsive”, which lets you change screen size using the little grab-bars around the edge.
Now let’s implement a sticky navigation header. Here’s the HTML/CSS.
.sticky-header {
position: -webkit-sticky;
position: sticky;
background-color: var(--clr-header);
top: 0;
padding: 10px 0;
z-index: 1000;
}
<header class="sticky-header">
<nav>
<ul>
<li><a href="#about" class="link-animate">About</a></li>
<li><a href="#blog" class="link-animate">Blog</a></li>
<li><a href="#projects" class="link-animate">Projects</a></li>
<li><a href="#contact" class="link-animate">Contact</a></li>
</ul>
</nav>
</header>
What IS sticky, you say? I forget, so I’ll look it up on Mozilla
I explored fixed an sticky. Setting position to fixed takes the header out of the normal document flow, which in this case is bad because the content of the website then starts at the top of the page, under the navigation header. You can get around this by adding top padding to the first section of the website, but that’s a bit of a workaround when we have sticky. Sticky keeps the header in the normal document flow so that the content of the website naturally follows it and does not get cut off.
Next, and this is easy, gander the background-color; hold on; ok, Gander Mountain is like a camping outdoor store; or an RV dealer; it got acquired in 2017...too boring. Anyway, background-color’s got an alpha on it! See that ‘/ 90%’? That means the background is almost opaque but not quite, so when the underlings scroll beneath (on account of the "z-index: 1000”, which means the header’s like 1000 times better!) you can still kinda see ‘em. Like if...ok I’m really falling down on the Googler here, I only watched like a clip of this British reality show where there’s a fake aristocratic family and fake servants and something about a dirty kitchen towel; no idea what it’s called; but it’s like if they had frosted glass installed instead of hardwood for the first floor and the big timers could casually look down at the shadowy servants trundling with their carts throughout the maze of basement corridors whilst enjoying a crumpet.
Now we got the sticky frosted header. How’d I get the underline effect when hovering over a link? Obviously Chat GPT.
.link-animate {
text-decoration: none;
position: relative;
}
.link-animate:after {
content: "";
position: absolute;
width: 0;
height: 1px;
background: currentColor;
left: 0;
bottom: 0;
transition: width 0.3s ease-out;
}
.link-animate:hover:after {
width: 100%;
}
This CSS works by first removing the default link underline behavior using text-decoration: none. Setting position to relative let’s you include your own custom line animation below the link text. The animate-link::after is a pseudo-element that does the work by positioning the underline starting at the bottom left with a transition that will animate the width of the 1 pixel high line. Setting the width to 0 “hides” the line when the mouse is not hovering over it. The animate-link:hover::after is the state entered when the mouse is hovering over the link, at which point the width is overridden to 100% and the line animates from left to right. Take the mouse off the link and the width is no longer overridden, the animation returning it to 0.
Now that we have a sticky frosted header with underline animation, what’s next? Layout!