Create responsive animated sticky nabar

In this tutorial we're going to learn how to create responsive animated sticky navbar with nav link animation using html css and Javascript

Click here to get starter files

🔗First let’s create the skeleton of the navbar

Markup of navbar

html
<header>
<nav class="nav" id="navbar">
<div class="logo">
<a href="index.html" id="logo">
<h1>coding sumit</h1>
</a>
</div>
<ul class="nav__list" id="navlinkitems">
<li class="nav__item">
<a href="#home-section" class="nav__link" id="home">Home</a>
</li>
<li class="nav__item">
<a href="#about-section" class="nav__link" id="about">About</a>
</li>
<li class="nav__item">
<a href="#skills-section" class="nav__link" id="service">Skills</a>
</li>
<li class="nav__item">
<a href="#projects-section" class="nav__link" id="work">Work</a>
</li>
<li class="nav__item">
<a href="#contacts-section" class="nav__link" id="contact">Contact</a>
</li>
</ul>
</nav>
</header>
Markup of navbar

🔗Let’s add styling into the ui

Basic styling

css
/* style.css */
html {
scroll-behavior: smooth;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
margin: 0;
font-family: "Source Sans Pro", sans-serif;
line-height: 1.6;
overflow-x: hidden;
background: #fff;
}
a {
text-decoration: none;
color: #111;
}
css
/* style.css */
.nav {
height: 5rem;
width: 100%;
display: block;
justify-content: flex-start;
z-index: 10;
font-weight: 300;
}
.nav__list {
list-style: none;
display: flex;
justify-content: flex-end;
margin-top: -49px;
padding: 0vh 4vw;
}
.nav__link {
color: inherit;
text-decoration: none;
margin-right: 50px;
position: relative;
font-family: "Raleway", sans-serif;
padding: 16px 0;
margin: 0 12px;
letter-spacing: 1px;
line-height: 16px;
font-weight: 700;
transition: color 0.1s, background-color 0.1s, padding 0.2s ease-in;
color: #111;
}
.logo {
padding: 3vh 5vw;
text-align: center;
display: flex;
align-items: center;
color: rgb(22, 8, 8);
text-transform: uppercase;
width: 25rem;
font-family: "Raleway", sans-serif;
font-weight: 800;
}
CSS for styling navbar, nav list , nav links & logo
css
/* style.css */
.nav__link::before {
content: "";
display: block;
position: absolute;
bottom: 3px;
left: 0;
height: 3px;
width: 100%;
background-color: #000;
transform-origin: right top;
transform: scale(0, 1);
transition: color 0.1s, transform 0.2s ease-out;
}
.nav__link:hover::before,
.nav__link:focus::before {
transform-origin: left top;
transform: scale(1, 1);
}

As you can see above video ☝️ at the end of this step when we hover it’s working as expected

🔗Let’s add some section in a page to enable scrolling for testing sticky navbar

Markup of sections

html
<section class="section one" id="home-section"></section>
<section class="section two" id="about-section"></section>
<section class="section three" id="skills-section"></section>
<section class="section four" id="projects-section"></section>
<section class="section five" id="contacts-section"></section>

CSS For styling sections

css
section {
width: 100%;
display: flex;
margin: auto;
align-items: center;
min-height: 110vh;
}
.one {
background-color: #fff;
}
.two {
background-color: rgb(190, 183, 170);
}
.three {
background-color: rgb(63, 118, 238);
}
.four {
background-color: rgb(221, 22, 88);
}
.five {
background-color: rgb(163, 114, 8);
}

But what about sticky navbar we want to make our navbar sticky on scroll for that we have to

  1. We have to add position: fixed on .nav css code
css
/* Style.css > .nav */
position: fixed;
  1. When we scrolls the page, execute scrollFunction in javascript file
js
// index.js
window.onscroll = function () {
scrollFunction();
};
function scrollFunction() {
document.getElementById("navbar").style.background = "#fff";
}

As you can see above ☝️ video when we scroll the page navbar stick on the top of the page

🔗Making navbar responsive

Before making navbar responsive we have to create

  1. Hamburger toggle menu to open and close navbar on mobile devices by clicking toggle button
  2. Small navbar logo for small devices

Let’s create hamburger toggle menu button

Markup of toggle button and hamburger

html
<button class="nav-toggle">
<span class="hamburger"></span>
</button>

Add styling into toggle button

css
.nav-toggle {
padding: 2.3em;
background: transparent;
border: 0;
cursor: pointer;
position: absolute;
right: 0.5rem;
top: 1.1rem;
z-index: 1000;
outline: none;
}

CSS code for .hamburger menu

css
.hamburger {
display: block;
position: relative;
}
.hamburger,
.hamburger::before,
.hamburger::after {
background-color: #111;
width: 2em;
height: 3px;
border-radius: 1em;
transition: transform 250ms ease-in-out;
}
.hamburger::before,
.hamburger::after {
content: "";
position: absolute;
left: 0;
right: 0;
}
.hamburger::before {
top: 6px;
}
.hamburger::after {
bottom: 6px;
}
CSS for hamburger menu

Let’s create .nav-open class ( we’ll toggle this class in navToggle click )

css
.nav-open .hamburger {
transform: rotate(0.625turn);
background-color: #111;
}
.nav-open .hamburger::before {
transform: rotate(90deg) translateX(-6px);
background-color: #111;
}
.nav-open .hamburger::after {
opacity: 0;
}

Let’s create functionality for toggle .nav-open class on click navToggle

js
// index.js
const navToggle = document.querySelector(".nav-toggle");
navToggle.addEventListener("click", () => {
document.body.classList.toggle("nav-open");
});

In above javascript code we selected the .nav-toggle class using querySelector and added a click event listener to navToggle then toggle .nav-open class to toggle hamburger

As you can see ☝️ above video hamburger menu working as expected but we don’t want that menu in desktop size we want that on mobile devices for that we have to add display:none in .nav-toggle class in style.css ( we’ll display this when we working on responsiveness later in this tutorial but at this moment we don’t want to show this toggle menu button in desktop device )

css
/* add display none to ..nav-toggle */
display: none;
hide humburger menu

Let’s create small navbar logo for small devices

html
<div class="smalllogo">
<a href="#welcome-section" class="logolink">
<h2><i class="fas fa-code"></i> coding sumit</h2>
</a>
</div>
css
.smalllogo {
padding: 4.7vh 8vw;
text-align: center;
align-items: center;
color: #111;
text-transform: uppercase;
font-family: "Raleway", sans-serif;
font-weight: 800;
display: flex;
}
small logo

As you can see above image ☝️ we have small logo but we don’t want to show this small logo on desktop devices for that we have to add display none to .smalllogo class similar how we did on .nav-toggle ( we’ll display this when we working on responsiveness later in this tutorial )

css
/* add display none to .smalllogo */
display: none;
hide small logo on desktop

Okay so at this point we have a small logo for small devices , hamburger menu button for toggling navbar open and close on small devices

Now let’s work on responsiveness

Create media queries with the condition max-width : 800px

css
/* style.css */
@media (max-width: 800px) {
}

In above css code we just defined media query and passed max-width : 800px as a condition It’s means when the size of the device less than 800px we want to applied specific styling for phone device

css
.logo {
display: none;
}
.smalllogo {
display: flex;
}
.nav-toggle {
display: block;
}

Add styling into navbar , nav lists

css
.nav {
display: flex;
justify-content: center;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 100;
transform: translateX(100%);
transition: transform 400ms cubic-bezier(0.51, 0.6, 0.54, 0.59);
height: 100vh;
}
.nav__list {
flex-direction: column;
justify-content: space-evenly;
text-align: center;
margin: 0;
padding: 135px;
background-color: #111;
width: 100%;
}
.nav__link {
margin: 0;
color: #fff;
}

In above code we added styling into navbar for small device and transformed the whole navbar to translateX(100%)

Transform navbar to translateX(0) on click toggle button

css
.nav-open {
overflow: hidden;
}
.nav-open .nav {
transform: translateX(0);
width: 100vw;
}

As you can see above video after clicking we’re able to toggle navbar but we getting one problem The problem is after click on toggle button we not able to see toggle button for closing navbar Reason for this problem is that we defined the black background-color of hamburger in css code

To display toggle hamburger button to close navbar we have to update .hamburger and hamburger::before on .nav-open in media query block

css
/* Update .hamburger and hamburger::before on .nav-open as follows in media query block */
.nav-open .hamburger {
transform: rotate(0.625turn);
background-color: #fff;
}
.nav-open .hamburger::before {
transform: rotate(90deg) translateX(-6px);
background-color: #fff;
}
css
.nav__link::before {
content: "";
display: block;
position: absolute;
bottom: 3px;
left: 0;
height: 3px;
width: 100%;
background-color: #fff;
transform-origin: right top;
transform: scale(0, 1);
transition: color 0.1s, transform 0.2s ease-out;
}

As you can see above link hover working as expected

js
// index.js
navLinks.forEach((link) => {
link.addEventListener("click", () => {
document.body.classList.remove("nav-open");
});
});

Congratulation we have successfully created responsive animated sticky navbar 🥳

Download source code