Sticky Headers In HTML CSS (Very Simple Examples)

Welcome to a quick tutorial on how to create sticky headers in HTML and CSS. So you want a header or navbar to stay at the top of the page?

There are 2 easy ways to create a sticky header in HTML CSS:

  • <header style="position:sticky; top:0;"> This will stick the header to the top as the user scrolls down.
  • <header style="position:fixed; top:0; left:0; width:100%"> This will permanently fix the header at the top.

Yep, it’s that simple. But let us walk through detailed examples in this guide, read on!

 

 

TABLE OF CONTENTS

 

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

 

EXAMPLE CODE DOWNLOAD

Source code on GitHub Gist

Just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

SORRY FOR THE ADS...

But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.

Buy Me A Coffee Code Boxx eBooks

 

 

STICKY HEADERS

All right, let us now get into the examples of the sticky headers in HTML and CSS.

 

TUTORIAL VIDEO

 

EXAMPLE 1) STICK HEADER AS THE USER SCROLLS

1A) DEMO

TOP NAV
HEADER
CONTENTS

 

1B) THE HTML

1-sticky.html
<!-- (A) NAV BAR -->
<nav id="page-nav">TOP NAV</nav>

<!-- (B) STICKY HEADER -->
<header id="page-head">HEADER</header>

<!-- (C) CONTENTS -->
<main id="page-main">CONTENTS</main>

There are 3 sections on this dummy page.

  1. <nav id="page-nav"> A top navigation bar, this one does not stick.
  2. <header id="page-head"> The sticky page header.
  3. <main id="page-main"> Main contents.

 

1C) THE CSS

1-sticky.css
/* (A) STICKY HEADER */
#page-head { position: sticky; top: 0; z-index: 9; }
  • As in the above snippet, we only need to add position: sticky; top: 0; to create the sticky header.
  • z-index: 9 will make sure that the header is layered above other elements; Just give this a higher number if it gets covered by another “floating element”.

 

 

EXAMPLE 2) FIXED HEADER

2A) DEMO

HEADER
CONTENT

 

2B) THE HTML

2-fixed.html
<!-- (A) STICKY HEADER -->
<header id="page-head">HEADER</header>

<!-- (B) CONTENTS -->
<main id="page-main">CONTENTS</main>

This should be very straightforward, just your usual:

  1. <header id="page-head"> Fixed header.
  2. <main id="page-main"> Contents.

 

2C) THE CSS

2-fixed.css
/* (A) HEADER */
#page-head {
  position: fixed; top: 0; left: 0; z-index: 9; /* fixed at top */
  width: 100%; height: 60px; padding: 10px; /* dimensions */
  display: flex; align-items: center; /* alignment */
}

/* (B) CONTENTS */
/* add top spacing to prevent being covered by header */
#page-main { margin-top: 80px; padding: 10px; }

This is an old-school method, when we didn’t have sticky to work with. A little bit roundabout:

  1. Set the header.
    • position: fixed; top: 0; left: 0; z-index: 9; Permanently fixed at the top of the window.
    • width: 100%; height: 60px; padding: 10px; Set the dimensions of the fixed header bar.
    • display: flex; align-items: center; Actually optional, but makes the header look nicer.
  2. The header is permanently fixed at the top of the window, and we don’t want the contents to be covered under it. Thus, margin-top: 80px will deliberately leave empty space at the top for the header.

 

 

EXAMPLE 3) DETECTING WHEN A HEADER IS “STUCK”

3A) DEMO

TOP NAV
HEADER
CONTENTS

 

3B) THE HTML

3-stuck.html
<!-- (A) NAV BAR -->
<nav id="page-nav">TOP NAV</nav>

<!-- (B) STICKY HEADER -->
<header id="page-head">HEADER</header>

<!-- (C) CONTENTS -->
<main id="page-main">CONTENTS</main>

Look no further, this is the same as the previous example. But we will be applying a different background color to the header navbar when it is “stuck” on top.

 

3C) THE CSS

3-stuck.css
/* (A) STICKY HEADER */
#page-head { position: sticky; top: -1px; z-index: 9; }
#page-head.stuck { background: red; }

How do we detect if the header navbar has been “stuck” to the top? Sadly, there is no CSS :stuck pseudo-class, but we do have a little trick to detect “stuck”. Take note of how we displace the header to top: -1px.

 

3D) THE JAVASCRIPT

3-stuck.js
window.addEventListener("load", () => {
  const observer = new IntersectionObserver( 
    ([e]) => e.target.classList.toggle("stuck", e.intersectionRatio < 1),
    { threshold: [1] }
  );
  observer.observe(document.getElementById("#page-head"));
});

Credits to David Walsh for this nifty trick.

  • Basically, the top position will shift when the header is stuck.
  • We are simply using Javascript IntersectionObserver to detect this change.
  • When the header is stuck, we apply a .stuck CSS class to it.

 

 

EXTRAS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

DESIGN CONSIDERATIONS – MOBILE SUPPORT

Before you plaster sticky headers all over your website, please consider if it adds more to the usability of the website. “Sticky interface” may work well on big screens, but it becomes a problem on small mobile screens instead – They don’t have a lot of space, and having a fixed header makes even less space to display content.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!