1. Web Design
  2. HTML

Create an Animated Sticky Header on Scroll (With a Bit of JavaScript)

Scroll to top

In the past, we’ve covered many header scroll effects, and today it’s time for another one! In this tutorial, you’ll learn how to make a header reappear and become sticky after a certain amount of scrolling.

Final product imageFinal product imageFinal product image
What You'll Be Creating

And to give the end result that extra something, we’ll use a frosty blur effect for our sticky nav bar.

What We’re Building

Here’s what we're going to create (scroll to test the behavior):

1. Begin With the Page Markup (HTML)

We’ll work with a typical page markup: a header and some sections below it for testing the effect. Inside the header, we’ll position the logo and a call-to-action. In your case, you can have many more elements like the menu, a search bar, a language switcher, etc. 

Here’s the markup:

1
<header class="page-header">
2
  <div class="container">
3
    <nav>
4
      <a href="">
5
        <img width="178" height="38" src="horizontal-logo-mobile.svg" alt="forecastr logo">
6
      </a>
7
      <button type="button">
8
        GET STARTED
9
        <svg xmlns="https://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24">
10
          <path d="M7.411 21.39l-4.054 2.61-.266-1.053c-.187-.744-.086-1.534.282-2.199l2.617-4.729c.387 1.6.848 3.272 1.421 5.371zm13.215-.642l-2.646-4.784c-.391 1.656-.803 3.22-1.369 5.441l4.032 2.595.266-1.053c.186-.743.085-1.533-.283-2.199zm-10.073 3.252h2.895l.552-2h-4l.553 2zm1.447-24c-3.489 2.503-5 5.488-5 9.191 0 3.34 1.146 7.275 2.38 11.809h5.273c1.181-4.668 2.312-8.577 2.347-11.844.04-3.731-1.441-6.639-5-9.156zm.012 2.543c1.379 1.201 2.236 2.491 2.662 3.996-.558.304-1.607.461-2.674.461-1.039 0-2.072-.145-2.641-.433.442-1.512 1.304-2.824 2.653-4.024z" />
11
        </svg>
12
      </button>
13
    </nav>
14
  </div>
15
</header>
16
17
<!-- sections here -->

2. Set the Header Styles (CSS)

For the sake of simplicity, we won’t discuss the initial reset and section styles, but feel free to look at them by clicking on the CSS tab of the demo project.

Anyhow, nothing fancy with our header appearance, as you can see below:

The header layoutThe header layoutThe header layout

The only important thing to note is that the header will be absolutely positioned at first. We’ll also give it a background with alpha transparency as that’s needed for the frosty filter effect we’ll apply later.

The header styles are as follows:

1
.page-header {
2
  position: absolute;
3
  top: 0;
4
  right: 0;
5
  left: 0;
6
  padding: 20px 0;
7
  z-index: 1;
8
  background-color: rgba(255, 255, 255, 0.15);
9
}
10
11
.page-header nav {
12
  display: flex;
13
  align-items: center;
14
  justify-content: space-between;
15
}
16
17
.page-header button {
18
  display: flex;
19
  align-items: center;
20
  font-size: 16px;
21
  font-weight: bold;
22
  padding: 14px 20px;
23
  border-radius: 10px;
24
  color: white;
25
  background: #08a6df;
26
  transition: background 0.3s;
27
}
28
29
.page-header button svg {
30
  flex-shrink: 0;
31
  margin-left: 5px;
32
  fill: currentColor;
33
}
34
35
.page-header button:hover {
36
  background: #0ab8f6;
37
}

3. Animate on Scroll (JavaScript)

As we scroll within the page, we’ll keep track of how much we have scrolled, and under a certain amount of scrolling (150px), we‘ll permanently show the header by toggling the is-sticky class.

At that point, the following actions will take place:

  • The header position will change from absolute to fixed. In this way, it’ll stay visible as we scroll.
  • As we scroll down, the header will smoothly appear with a slide-in animation. On the other hand, as we scroll up, it’ll immediately disappear when we’re near the top of the page (≤150px).
  • We’ll use the backdrop-filter property to blur anything behind the header.
  • We’ll make the header smaller by reducing its vertical paddings, the logo dimensions, and the button’s size and paddings. 

Here’s the required JavaScript code:

1
const header = document.querySelector(".page-header");
2
const toggleClass = "is-sticky";
3
4
window.addEventListener("scroll", () => {
5
  const currentScroll = window.pageYOffset;
6
  if (currentScroll > 150) {
7
    header.classList.add(toggleClass);
8
  } else {
9
    header.classList.remove(toggleClass);
10
  }
11
});

And the associated styles:

Note the backdrop-filter: blur(10px); for our frosty blurred effect
1
.page-header.is-sticky {
2
  position: fixed;
3
  box-shadow: 0 5px 16px rgba(0, 0, 0, 0.1);
4
  padding: 8px 0;
5
  backdrop-filter: blur(10px);
6
  animation: slideDown 0.35s ease-out;
7
}
8
9
.page-header.is-sticky img {
10
  max-width: 80%;
11
}
12
13
.page-header.is-sticky button {
14
  font-size: 14px;
15
  padding: 7px 10px;
16
}
17
18
@keyframes slideDown {
19
  from {
20
    transform: translateY(-100%);
21
  }
22
  to {
23
    transform: translateY(0);
24
  }
25
}

Conclusion

Done! During this short exercise, we learned how to alter a header’s behavior on scroll by making it sticky. You can take advantage of this effect in cases where you need a lighten/shrunken version of your header on scroll. For example, you want to keep some core elements like the logo and menu, yet hide secondary ones like the search bar or some call-to-action buttons.

Let’s look again at our creation:

As always, thanks a lot for reading!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.