Sticky/ Dynamic Navbar by Using react-headroom

May 25 20239 minutes
Video Tutorial

You must have seen Navbars on some websites that hide and show when you scroll a little bit, that’s called Sticky or Dynamic Navbar.

You can implement this yourself in React using your React skills, but if you want to save some time and use a ready-made React component to implement Dynamic Navbar in your React app, there’s a React package called react-headroom.

React Headroom gives out-of-the-box sticky hide and shows behavior with a very smooth transition and you can apply it on any component but it’s mainly used for Headers or Navbars.

To demonstrate this I am going to create a new React project and use react-headroom in that.

#Creating New React Project

First of I am going to create a new React project but if you already have a project created then you can skip this part.

To create a new react App you can you npm create-react-app projectName or you can use any other build tools like Vite or create a Next Js app.

After creating my new React App and some changes my App.js looks like this

import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <h1>Hello Coders!</h1>
     
    </div>
  );
}

#Creating a simple Navbar

We’ll create a simple Navbar in our app so that we can make it sticky later.

Let’s just add some navigation links like Home, About Us, and Contact Us in Navbar

import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <header>
        <nav>
          <ul className="nav-links">
            <li>
              <a href="/">Home</a>
            </li>
            <li>
              <a href="/about">About Us</a>
            </li>
            <li>
              <a href="/contact">Contact Us</a>
            </li>
          </ul>
        </nav>
      </header>
      <h1>Hello Coders!</h1>
    </div>
  );
}

We are going to style it a little bit with CSS in style.css file

* {
  margin: 0; /* removing unnecessary margins from document*/
}

.App {
  font-family: sans-serif;
  text-align: center;
}
header {
  background-color: #90ffb2; /* Canging bg color to make it look different from content body*/
  padding: 10px;
}
.nav-links {
  list-style-type: none; /* Remove bullet dots */
  display: flex; /* Display the navigation links horizontally */
  justify-content: center; /* Center the navigation links horizontally */
  padding: 0; /* Remove default padding */
}

.nav-links li {
  margin-right: 20px; /* Add some spacing between the navigation links */
}

#Adding dummy content

We have to make our page longer in order to make it scrollable so that we can see the behavior of the header when we scroll.

Lets add some dummy paragraphs.

import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <header>
        <nav>
          <ul className="nav-links">
            <li>
              <a href="/">Home</a>
            </li>
            <li>
              <a href="/about">About Us</a>
            </li>
            <li>
              <a href="/contact">Contact Us</a>
            </li>
          </ul>
        </nav>
      </header>
      <h1>Hello Coders!</h1>
      <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut accumsan pretium neque eu imperdiet. Integer eget suscipit sapien. Vivamus non massa ex. Aliquam et lacus id diam vulputate elementum. Nunc viverra maximus nulla, vel gravida mi mollis et. Sed dictum tempor nulla, at hendrerit mauris condimentum non. Maecenas non mi nec purus molestie dictum.

Nam malesuada iaculis imperdiet. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent consequat justo vitae facilisis dapibus. Integer feugiat aliquet felis, ac pellentesque ligula convallis non. Vivamus commodo eu mauris non tincidunt. Vivamus quis arcu fermentum, viverra libero quis, varius orci. Pellentesque augue ante, posuere ut ultrices et, volutpat at ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean aliquam urna mi, ac ornare nisl euismod sit amet. Nullam a ligula in sapien imperdiet lobortis. Cras fringilla ornare leo, non feugiat neque egestas et. Ut laoreet lorem vel pulvinar pellentesque. Donec ut tortor ut velit maximus vulputate. Aliquam placerat arcu at nibh viverra blandit.

Nam auctor quis ligula vel maximus. Nam ac placerat nunc. Vivamus eget nibh sit amet ex bibendum suscipit. Suspendisse malesuada eros eget diam malesuada feugiat. Pellentesque id sollicitudin nulla. Praesent blandit mattis gravida. Duis varius mauris sit amet diam fermentum elementum. Etiam lacinia condimentum elit, non ornare purus finibus eu. Ut tempor mollis odio vitae facilisis. Curabitur quis ligula augue. Aliquam scelerisque scelerisque risus, eu consectetur turpis aliquam nec. Etiam a justo id orci ultrices sagittis quis eget massa. Vestibulum diam nunc, venenatis nec ipsum hendrerit, vehicula scelerisque diam. Mauris ornare convallis massa sit amet sollicitudin.

Aliquam nec justo maximus velit fringilla fringilla et ut dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Proin et elit mattis, vestibulum nulla dignissim, tempus ligula. Sed id turpis varius, luctus mauris eu, suscipit felis. Aliquam euismod tincidunt mauris ac posuere. Mauris efficitur bibendum orci, eget convallis libero hendrerit vitae. Etiam suscipit dui purus, ut volutpat neque tristique quis. Suspendisse potenti. Vivamus egestas, augue at semper efficitur, dui massa euismod odio, in consectetur velit nisi dignissim orci. Aenean sit amet ultrices arcu, eget rhoncus est. Sed tempor hendrerit accumsan. Pellentesque tempor maximus posuere. Donec in finibus ex, at volutpat odio.

Aenean at erat et velit lacinia vehicula. Praesent a magna vitae dolor rhoncus ullamcorper ac at est. Nulla imperdiet elit eget lectus egestas, quis molestie erat pulvinar. Quisque eget nisl dapibus, mattis eros id, euismod risus. Nam dignissim leo non metus placerat, eget pellentesque dolor mollis. Pellentesque eu aliquam turpis. Curabitur mauris turpis, vestibulum ac placerat nec, semper at mi. Nam ornare turpis eu ornare pharetra. Quisque eleifend velit magna, nec accumsan orci porttitor a.
      </p>
    </div>
  );
}

Now our app looks like this

image from tutorend.com

#Installing react-headroom package

To implement a sticky navbar we are going to use react-headroom which is an NPM package so in order to use it in our app we need to install it.

You can also follow the official documentation for this package by clicking here.

To install this package run the following command in the terminal.

npm install react-headroom

#Importing Headroom component

Now that the package has been successfully installed we can use it as a component anywhere in your app.

We can import the Headroom component from react-headroom like this.

import Headroom from "react-headroom";

#Using Headroom component

Now it is time to use the Headroom component to make our header sticky and dynamic when we scroll.

We just need to wrap our header inside <Headroom> </Headroom> and everything will be handled automatically.

import "./styles.css";
import Headroom from "react-headroom";
export default function App() {
  return (
    <div className="App">
      <Headroom>
        <header>
          <nav>
            <ul className="nav-links">
              <li>
                <a href="/">Home</a>
              </li>
              <li>
                <a href="/about">About Us</a>
              </li>
              <li>
                <a href="/contact">Contact Us</a>
              </li>
            </ul>
          </nav>
        </header>
      </Headroom>
      <h1>Hello Coders!</h1>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut accumsan
        pretium neque eu imperdiet. Integer eget suscipit sapien. Vivamus non
        massa ex. Aliquam et lacus id diam vulputate elementum. Nunc viverra
        maximus nulla, vel gravida mi mollis et. Sed dictum tempor nulla, at
        hendrerit mauris condimentum non. Maecenas non mi nec purus molestie
        dictum. Nam malesuada iaculis imperdiet. Interdum et malesuada fames ac
        ante ipsum primis in faucibus. Praesent consequat justo vitae facilisis
        dapibus. Integer feugiat aliquet felis, ac pellentesque ligula convallis
        non. Vivamus commodo eu mauris non tincidunt. Vivamus quis arcu
        fermentum, viverra libero quis, varius orci. Pellentesque augue ante,
        posuere ut ultrices et, volutpat at ipsum. Pellentesque habitant morbi
        tristique senectus et netus et malesuada fames ac turpis egestas. Aenean
        aliquam urna mi, ac ornare nisl euismod sit amet. Nullam a ligula in
        sapien imperdiet lobortis. Cras fringilla ornare leo, non feugiat neque
        egestas et. Ut laoreet lorem vel pulvinar pellentesque. Donec ut tortor
        ut velit maximus vulputate. Aliquam placerat arcu at nibh viverra
        blandit. Nam auctor quis ligula vel maximus. Nam ac placerat nunc.
        Vivamus eget nibh sit amet ex bibendum suscipit. Suspendisse malesuada
        eros eget diam malesuada feugiat. Pellentesque id sollicitudin nulla.
        Praesent blandit mattis gravida. Duis varius mauris sit amet diam
        fermentum elementum. Etiam lacinia condimentum elit, non ornare purus
        finibus eu. Ut tempor mollis odio vitae facilisis. Curabitur quis ligula
        augue. Aliquam scelerisque scelerisque risus, eu consectetur turpis
        aliquam nec. Etiam a justo id orci ultrices sagittis quis eget massa.
        Vestibulum diam nunc, venenatis nec ipsum hendrerit, vehicula
        scelerisque diam. Mauris ornare convallis massa sit amet sollicitudin.
        Aliquam nec justo maximus velit fringilla fringilla et ut dolor.
        Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
        cubilia curae; Proin et elit mattis, vestibulum nulla dignissim, tempus
        ligula. Sed id turpis varius, luctus mauris eu, suscipit felis. Aliquam
        euismod tincidunt mauris ac posuere. Mauris efficitur bibendum orci,
        eget convallis libero hendrerit vitae. Etiam suscipit dui purus, ut
        volutpat neque tristique quis. Suspendisse potenti. Vivamus egestas,
        augue at semper efficitur, dui massa euismod odio, in consectetur velit
        nisi dignissim orci. Aenean sit amet ultrices arcu, eget rhoncus est.
        Sed tempor hendrerit accumsan. Pellentesque tempor maximus posuere.
        Donec in finibus ex, at volutpat odio. Aenean at erat et velit lacinia
        vehicula. Praesent a magna vitae dolor rhoncus ullamcorper ac at est.
        Nulla imperdiet elit eget lectus egestas, quis molestie erat pulvinar.
        Quisque eget nisl dapibus, mattis eros id, euismod risus. Nam dignissim
        leo non metus placerat, eget pellentesque dolor mollis. Pellentesque eu
        aliquam turpis. Curabitur mauris turpis, vestibulum ac placerat nec,
        semper at mi. Nam ornare turpis eu ornare pharetra. Quisque eleifend
        velit magna, nec accumsan orci porttitor a.
      </p>
    </div>
  );
}

And now we successfully made our header dynamic, when we scroll down it will disappear and when we scroll up it will show up after scrolling for a second.

You can see the live demo of it on code sandbox.

#Other props and customization

#Customization

The React Headroom component is designed to be effortlessly integrated into your project, providing default animation settings that work seamlessly. However, if you wish to override the default animation, you have two options available.

The first option is to override the inline styles directly within the component. Here’s an example of how you can achieve this:

<Headroom style={{
  WebkitTransition: 'all .5s ease-in-out',
  MozTransition: 'all .5s ease-in-out',
  OTransition: 'all .5s ease-in-out',
  transition: 'all .5s ease-in-out'
}}>
  <h1>You can place any content you desire within the Headroom Component</h1>
</Headroom>

Alternatively, you can utilize CSS to customize the animation. The component includes a headroom class, along with headroom–pinned or headroom–unpinned classes based on its pinned state.

.headroom {
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
}

.headroom--unfixed {
  position: relative;
  transform: translateY(0);
}

.headroom--scrolled {
  transition: transform 200ms ease-in-out;
}

.headroom--unpinned {
  position: fixed;
  transform: translateY(-100%);
}

.headroom--pinned {
  position: fixed;
  transform: translateY(0%);
}

As inline styles take precedence over CSS, you need to disable the inline styles by using the disableInlineStyles prop.

#Additional Props

The React Headroom component offers several other props to enhance its functionality and customization:

  1. onPin: A callback function that is invoked when the header is pinned.
  2. onUnpin: A callback function that is triggered when the header is unpinned.
  3. onUnfix: A callback function that is called when the header is no longer in a fixed position.
  4. upTolerance: Specifies the scroll tolerance in pixels when scrolling up before the component is pinned.
  5. downTolerance: Sets the scroll tolerance in pixels when scrolling down before the component is pinned.
  6. disable: Disables the pinning and unpinning behavior of the component.
  7. wrapperStyle: Allows you to pass custom styles for the wrapper, maintaining the component’s vertical space at the top of the page.
  8. parent: Provides a custom “parent” element for scroll events. The parent prop should be a function that resolves to the desired element.
  9. pinStart: Specifies the height in pixels where the header should start and stop pinning. This is useful when you have another element above the Headroom component.


These additional props provide you with further control and flexibility over the behavior and appearance of the React Headroom component.