Clue Mediator

Animated sticky header on scroll using JavaScript

📅May 1, 2020

When you create a website where you may need to implement the sticky or fixed header navigation menu with smooth animation on page scroll using JavaScript and CSS. So today we’ll show you how to create an animated sticky header on scroll using JavaScript.

Sticky Header Navigation With Smooth Scroll | Free jQuery, Smooth scroll header with fixed position, Smooth scrolling fixed header, Smooth scroll with navbar fixed top, Simple sticky/fixed header that animates on scroll, How to create an animated sticky header after some scrolling, sticky navigation bar on scroll, Fixed header with scrolling content example.

Checkout more articles on JavaScript

Way to create an animated sticky header on scroll

  1. Create sample website in HTML
  2. Add JavaScript code
  3. Add styles
  4. Output

1. Create a sample website in HTML

Let’s create a simple website in HTML to show you the sticky header functionality on page scroll. For demo purposes we have created all codes in a single file.

index.html





  <title>Animated sticky header on scroll using JavaScript - Clue Mediator</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    * {
      box-sizing: border-box;
    }

    body {
      font-family: Arial, Helvetica, sans-serif;
      margin: 0;
    }

    .header {
      padding: 80px;
      text-align: center;
      color: white;
      background-image: url("./images/head-img.jpg");
      background-size: cover;
    }

    .header h1 {
      font-size: 40px;
    }

    .navbar {
      overflow: hidden;
      background: #269faf;
    }

    .navbar a {
      float: left;
      display: block;
      color: white;
      text-align: center;
      padding: 14px 20px;
      text-decoration: none;
    }

    .navbar a.right {
      float: right;
    }

    .navbar a:hover {
      background-color: #ddd;
      color: black;
    }

    .row {
      display: -ms-flexbox;
      display: flex;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
    }

    .side {
      -ms-flex: 30%;
      flex: 30%;
      background-color: #f1f1f1;
      padding: 20px;
    }

    .main {
      -ms-flex: 70%;
      flex: 70%;
      background-color: white;
      padding: 20px;
    }

    .fakeimg {
      width: 100%;
      max-height: 300px;
      object-fit: cover;
      border-radius: 4px;
    }

    .footer {
      padding: 20px;
      text-align: center;
      background: #ddd;
    }

  </style>




  <div class="header">
    <h1>Sticky Header Website</h1>
    <p>A website created in HTML</p>
  </div>

  <div id="sticky-header" class="navbar">
    <a href="#">Home</a>
    <a href="#">About</a>
    <a href="#">Contact</a>
    <a href="#" class="right">Login</a>
  </div>

  <div class="row">
    <div class="main">
      <h2>Lorem ipsum dolor sit amet</h2>
      <h5>Arcu dui vivamus arcu felis bibendum</h5>
      <img class="fakeimg" src="./images/img-1.jpg">
      <p>Excepteur sint occaecat</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
        magna aliqua. Ipsum suspendisse ultrices gravida dictum fusce. Mauris pellentesque pulvinar pellentesque
        habitant morbi. Libero id faucibus nisl tincidunt eget nullam non. Rhoncus aenean vel elit scelerisque mauris
        pellentesque pulvinar pellentesque habitant.</p>
      <br>
      <h2>Vivamus arcu felis</h2>
      <h5>Tellus mauris a diam maecenas sed enim</h5>
      <img class="fakeimg" src="./images/img-2.jpg">
      <p>Ultrices tincidunt</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
        magna aliqua. Augue interdum velit euismod in pellentesque. Vivamus arcu felis bibendum ut tristique et.
        Tincidunt tortor aliquam nulla facilisi cras.</p>
      <br>
      <h2>Purus semper eget duis at tellus at urna</h2>
      <h5>Fermentum leo vel orci porta</h5>
      <img class="fakeimg" src="./images/img-3.jpg">
      <p>Tristique nulla aliquet</p>
      <p>Volutpat ac tincidunt vitae semper quis lectus nulla at volutpat. Dapibus ultrices in iaculis nunc sed augue.
        Senectus et netus et malesuada fames ac turpis.</p>
      <br>
      <h2>Fermentum dui faucibus in ornare quam</h2>
      <h5>Viverra nibh cras pulvinar</h5>
      <img class="fakeimg" src="./images/img-4.jpg">
      <p>Scelerisque mauris pellentesque</p>
      <p>Scelerisque pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Tempor orci eu
        lobortis elementum nibh tellus molestie nunc.</p>
    </div>
    <div class="side">
      <h2>Eget mi proin</h2>
      <h5>Sed libero enim:</h5>
      <img class="fakeimg" src="./images/s-img-1.jpg">
      <p>Massa tincidunt dui ut ornare lectus sit amet est.</p>
      <h3>Mi ipsum faucibus</h3>
      <p>Lorem ipsum dolor sit ame.</p>
      <img class="fakeimg" src="./images/s-img-2.jpg">
      <h3>Malesuada fames</h3>
      <p>In nisl nisi scelerisque eu ultrices.</p>
      <img class="fakeimg" src="./images/s-img-3.jpg">
    </div>
  </div>

  <div class="footer">
    <h2>Footer</h2>
  </div>

2. Add JavaScript code

To create a sticky header navigation bar we have to add the JavaScript code at the end of the `body` section.

<script>
  var header = document.getElementById("sticky-header");
  var stickyPosition = header.offsetTop + header.offsetHeight;
  window.onscroll = function () {
    if (window.pageYOffset > stickyPosition) {
      header.classList.add("sticky");
      document.querySelectorAll('body')[0].style.marginTop = header.offsetHeight + "px";
    } else {
      header.classList.remove("sticky");
      document.querySelectorAll('body')[0].style.marginTop = "0px";
    }
  };
</script>

Here first we tried to get the header element and calculate the position to stick it.

We have to create a function that executes on page scroll where we will check the position and add the `sticky` class in the header element when reaching its scroll position. Also we need to set the `marginTop` as much as the header height in the body element because we are updating the `position: fixed` in the sticky class.

3. Add styles

Finally, we will add the style of the `sticky` class and set the smooth animation for the navigation bar.

<style>
  .sticky {
    position: fixed;
    top: 0;
    width: 100%;
    transition: all 0.5s ease;
    animation: smoothScroll 1s forwards;
  }

  @keyframes smoothScroll {
    0% {
      transform: translateY(-142px);
    }
    100% {
      transform: translateY(0px);
    }
  }
</style>

4. Output

Let’s combine all code together and see the output.

index.html





  <title>Animated sticky header on scroll using JavaScript - Clue Mediator</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    * {
      box-sizing: border-box;
    }

    body {
      font-family: Arial, Helvetica, sans-serif;
      margin: 0;
    }

    .header {
      padding: 80px;
      text-align: center;
      color: white;
      background-image: url("./images/head-img.jpg");
      background-size: cover;
    }

    .header h1 {
      font-size: 40px;
    }

    .navbar {
      overflow: hidden;
      background: #269faf;
    }

    .navbar a {
      float: left;
      display: block;
      color: white;
      text-align: center;
      padding: 14px 20px;
      text-decoration: none;
    }

    .navbar a.right {
      float: right;
    }

    .navbar a:hover {
      background-color: #ddd;
      color: black;
    }

    .row {
      display: -ms-flexbox;
      display: flex;
      -ms-flex-wrap: wrap;
      flex-wrap: wrap;
    }

    .side {
      -ms-flex: 30%;
      flex: 30%;
      background-color: #f1f1f1;
      padding: 20px;
    }

    .main {
      -ms-flex: 70%;
      flex: 70%;
      background-color: white;
      padding: 20px;
    }

    .fakeimg {
      width: 100%;
      max-height: 300px;
      object-fit: cover;
      border-radius: 4px;
    }

    .footer {
      padding: 20px;
      text-align: center;
      background: #ddd;
    }

    .sticky {
      position: fixed;
      top: 0;
      width: 100%;
      transition: all 0.5s ease;
      animation: smoothScroll 1s forwards;
    }

    @keyframes smoothScroll {
      0% {
        transform: translateY(-142px);
      }

      100% {
        transform: translateY(0px);
      }
    }
  </style>




  <div class="header">
    <h1>Sticky Header Website</h1>
    <p>A website created in HTML</p>
  </div>

  <div id="sticky-header" class="navbar">
    <a href="#">Home</a>
    <a href="#">About</a>
    <a href="#">Contact</a>
    <a href="#" class="right">Login</a>
  </div>

  <div class="row">
    <div class="main">
      <h2>Lorem ipsum dolor sit amet</h2>
      <h5>Arcu dui vivamus arcu felis bibendum</h5>
      <img class="fakeimg" src="./images/img-1.jpg">
      <p>Excepteur sint occaecat</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
        magna aliqua. Ipsum suspendisse ultrices gravida dictum fusce. Mauris pellentesque pulvinar pellentesque
        habitant morbi. Libero id faucibus nisl tincidunt eget nullam non. Rhoncus aenean vel elit scelerisque mauris
        pellentesque pulvinar pellentesque habitant.</p>
      <br>
      <h2>Vivamus arcu felis</h2>
      <h5>Tellus mauris a diam maecenas sed enim</h5>
      <img class="fakeimg" src="./images/img-2.jpg">
      <p>Ultrices tincidunt</p>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
        magna aliqua. Augue interdum velit euismod in pellentesque. Vivamus arcu felis bibendum ut tristique et.
        Tincidunt tortor aliquam nulla facilisi cras.</p>
      <br>
      <h2>Purus semper eget duis at tellus at urna</h2>
      <h5>Fermentum leo vel orci porta</h5>
      <img class="fakeimg" src="./images/img-3.jpg">
      <p>Tristique nulla aliquet</p>
      <p>Volutpat ac tincidunt vitae semper quis lectus nulla at volutpat. Dapibus ultrices in iaculis nunc sed augue.
        Senectus et netus et malesuada fames ac turpis.</p>
      <br>
      <h2>Fermentum dui faucibus in ornare quam</h2>
      <h5>Viverra nibh cras pulvinar</h5>
      <img class="fakeimg" src="./images/img-4.jpg">
      <p>Scelerisque mauris pellentesque</p>
      <p>Scelerisque pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Tempor orci eu
        lobortis elementum nibh tellus molestie nunc.</p>
    </div>
    <div class="side">
      <h2>Eget mi proin</h2>
      <h5>Sed libero enim:</h5>
      <img class="fakeimg" src="./images/s-img-1.jpg">
      <p>Massa tincidunt dui ut ornare lectus sit amet est.</p>
      <h3>Mi ipsum faucibus</h3>
      <p>Lorem ipsum dolor sit ame.</p>
      <img class="fakeimg" src="./images/s-img-2.jpg">
      <h3>Malesuada fames</h3>
      <p>In nisl nisi scelerisque eu ultrices.</p>
      <img class="fakeimg" src="./images/s-img-3.jpg">
    </div>
  </div>

  <div class="footer">
    <h2>Footer</h2>
  </div>

  <script>
    var header = document.getElementById("sticky-header");
    var stickyPosition = header.offsetTop + header.offsetHeight;
    window.onscroll = function () {
      if (window.pageYOffset > stickyPosition) {
        header.classList.add("sticky");
        document.querySelectorAll('body')[0].style.marginTop = header.offsetHeight + "px";
      } else {
        header.classList.remove("sticky");
        document.querySelectorAll('body')[0].style.marginTop = "0px";
      }
    };
  </script>

Output - Animated sticky header on scroll using JavaScript - Clue Mediator

Output - Animated sticky header on scroll using JavaScript - Clue Mediator

Demo & Source Code

Github Repository