Sticky navbar from scratch using react
Tags: react, header, stickynavbar, stickyheader
Published: 2020-06-21 09:29:19

In many modern websites, you must have seen this effect of Navigation bar/ Header sticking to the top of the page even if you scroll down the page for your better navigation so you don’t have to go up always to choose between links for moving between the pages. Haven’t you?
If you have and are curious about how does that work, then this post is your go-to guide to create that very simple yet beautiful effect/feature for you next project which adds better UX to the page.
What are you waiting for? Let’s get started 🚀

# Initial Setup

First, we are going to create a react-app from start. For that enter this command in your favourite terminal

```
create-react-app sticky-navbar
```

We are going to delete some of the files created out of the box from create-react-app. After deleting some files, project directory will look like this:
![Starting structure](https://rohitdalal.com/static/b94770cced20364c85bd70580eb850c5/906b5/file-structure.png)

We will start by creating components, two components will suffice for this little project. Create a directory called Components in /src and add two files Navbar.js and Content.js
Start by editing App.js. Add the following code to start with a basic layout


```
//App.js
import React from 'react';
import Navbar from './components/Navbar';
import Content from './components/Content';
function App() {
  return (
    <div className="App">
      <Navbar />
      <Content />
    </div>
  );
}
export default App;
```

Here we are rendering two functional components Navbar and Content, their name clearly explains their purpose.
This below code fills up Navbar.js. Navbar component is basically a header section which consists of your website Logo and one navigation menu with 4/5 links

```
//Navbar.js
import React from 'react';
import './navbar.scss';
import Logo from './../img/logo.svg';
const Navbar=() => {
  return (
    <header className={navbarClasses.join(" ")}>
          
        <div className="logo">
            {/* your logo */}
        </div>
        <nav className="navigation">
            {/* your navigation */}
        </nav>
        
    </header>
  )
};
export default Navbar;
```

Now, it’s time to give some styling to the page. You can have your own set of styling or if you just want to use mine, copy below given styles to <code>navbar.scss</code>
```
//navbar.scss
.navbar{
  width: 100%;
  min-height: 6vh;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: #eee;
  transition: all .7s ease-in;
}
//IMPORTANT
.scrolled{
  position: fixed;
  top: 0;
  left: 0;
  background-color: lightblue;
}
.logo img{
  width: 50px;
}
.navigation{
    //your navigation styles
}
```

Now, we would fill up Content.js with some meat to add some content on the page along with the Navbar.
This code fills up dummy boxes to take ample amount of height on-page. You can use any real-life content. This is just for demo

```
//Content.js
import React from 'react';
import './content.scss';
const Content=() => {
  const data=(
    <div className="box">
        <h2>My div content </h2>
    </div>
  );
return (
    <main className="content">
        {data}
        {data}
        {data}
        {data}
        {data}
    </main>
  )
}
export default Content;
```

Style for Content.js
```
//content.scss
.content{
    width: 80%;
    margin:2rem 10% 0 10%;
    max-width: 100%;
    box-sizing: border-box;
    min-height: 100vh;
}
.box{
    width:80%;
    margin:2rem 10% 0 10%;
    height:100vh;
    background-color:plum;
}
```

After all this setup, our page will look like this:
![Complete layout](https://rohitdalal.com/static/a9f5042544e19f53d399c35791f3a8e5/e996b/complete-layout.png)

# Main Logic

Now that we have our meat set up for the Sticky navbar, we will add the main Logic to get that sticky effect. For this, we are going to do a little bit of state-management using React hooks. If you are not aware of react-hooks, don’t worry about it. You can use normal state management with classful component too.
So, the idea is as you scroll down, you check for the scrollY (i.e. total height you have scrolled from the top in pixels ) in componentDidMount() or useEffect() using window.scrollY and if that scrolled height is greater than some value, say 200px in this case, then we change the class of our Navbar to navbar scrolled. Styles for .scrolled is already in your navbar.scss if you have copied my styles. I have used array approach to switch between classes from navbar to navbar scrolled.

Confused?

```
//Navbar.js
import React,{useEffect} from 'react';
import './navbar.scss';
const Navbar=() => {
  const [scrolled,setScrolled]=React.useState(false);
const handleScroll=() => {
    const offset=window.scrollY;
    if(offset > 200 ){
      setScrolled(true);
    }
    else{
      setScrolled(false);
    }
  }
   
  useEffect(() => {
    window.addEventListener('scroll',handleScroll)
  })
let navbarClasses=['navbar'];
  if(scrolled){
    navbarClasses.push('scrolled');
  }
  
   return (
    /* rest remains same*/
   )
};
export default Navbar;
```

In this way, we have successfully created our simple sticky Navbar from scratch.
If you want to look at the complete code, check my [GitHub](https://github.com/dalalRohit/sticky-navbar-tutorial) repo.


# Conclusion

This was all for this simple demo application. I hope this post was helpful to you and I’ve solved your problem by explaining it in your words. If you have any queries regarding this post, feel free to ask me personally. I will be happy to answer those on an individual level.
Thank you. Have a nice day!