How To Create a Fixed Header on Scroll

08/07/2020

One of the great things about Javascript is the DOM, or Document Object Model. The DOM is what allows Javascript to access the HTML element on the page, and modify or remove them.

Combined with event listeners, we can do some awesome stuff with Javascript. One of these things is animating a sticky header when the window is scrolled.

enter image description here

Setting Up Our Project

To create a simple demonstration of a sticky header on scroll, we're going create a newindex.htmlfile in a new project.

<header id="header">
  <div class="center header-container">
    <h1>Header Title</h1>
    <div class="menu">
      Menu
    </div>
  </div>
</header>
<section id="hero">
  <div class="center">
    <h1>A Headline</h1>
    <h3>About a website.</h3>
  </div>
</section>
<section>
  ...content
</section>
<script src="index.js"></script>

What we're doing here is creating a header component with an id ofheader, so we can access it from Javascript later and apply other styles.

We've got some placeholder content inside our header, which can be replaced with whatever you want in your header. Probably a menu 🤷‍♂️

The rest of the content is so the page can scroll. Because if the page doesn't scroll, we can't apply scroll-based styles to the header.

Huh. Who would have thought?

Styling the Header

To style the header, we need to add to style declarations.

  • The main header styles
  • The scrolled header styles

The basic header styles are as follows:

#header {
  background: transparent;
  position: fixed;
  top: 0;
  width: 100%;
  padding: 36px  0;
  margin: 0;
  height: fit-content;
  color: white;
  transition: all  .3s  ease-out;
}

We're setting the background to be transparent so it's whatever color the hero image is. We're also setting it'spositiontofixed. This is what allows the header to stay attached to the top of the page.

We also have to set thewidthto100%. If you don't do this to fixed-position elements, they won't be, well, full-width.

(You can also add a transition property as we've just done here: this will make the change in styles smoother for the header when the page is scrolled.)

Speaking of scrolling, we still have to add our styles for when the header is scrolled.

To do this, we'll create another CSS declaration for a class.scrolled.

#header.scrolled {
  padding: 16px  0;
  background: rgb(11, 199, 143);
}

Wow.

That was easy.

Basically, the only thing we need to do is add a new background (because a transparent background on a white page isn't good) and make the header slightly smaller.

Now, we have our header styled. However, it doesn't yet do anything on scroll.

enter image description here

Using Javascript to Update The Header Styles on Scroll

Now that we've got our styles set up, the only thing left to do is trigger a change for the header classname on scroll.

To do that, we turn to Javascript. Inside of a newindex.jsfile, we're going to add this code:

// Get header element from DOM
const  header = document.getElementById('header');

// Define onScroll function
const  onScroll = () => {
  const  scrollHeight = window.scrollY; // Get window scroll height

  if (scrollHeight > 50) {
    header.classList.add('scrolled'); // Add .scrolled class to header
  } else {
    header.classList.remove('scrolled'); // Remove .scrolled class from header
  }
};

document.addEventListener('scroll', onScroll); // Add event listener to window

It's a pretty simple bit of code: we get the header element using the DOM methodgetElementById. We then create anonScrollfunction that will decide whether or not to update the header styles. If the scroll height is greater than a defined value, we add the class.scrolledto our header.

header.classList.add('scrolled');

Otherwise, we remove it.

header.classList.remove('scrolled');

Finally, we add our event listener, which tells ouronScrollfunction when to run.

document.addEventListener('scroll', onScroll);

And that's it! Now we have a sticky header that changes height and background on scroll 🔥

Thanks for reading! If you liked this article, you can check me out onTwitter, or mywebsite!

p.s For those of you wondering, the official reading time for this article is 3 minutes and 2 seconds ⏳.