DEV Community

Cover image for Implementing Smooth Scroll Using Javascript ⚡
Rohan Kulkarni
Rohan Kulkarni

Posted on

Implementing Smooth Scroll Using Javascript ⚡

Hello Everyone 👋🏻, today we will be looking at how to implement smooth scrolling behavior using the scrollIntoView property.

Normally for the creation of Navbar, we use this code.

    <nav class="navbar" id="nav--bar">
        <ul>
            <li><a href="#1" class="link--a">DIV 1</a></li>
            <li><a href="#2" class="link--a">DIV 2</a></li>
            <li><a href="#3" class="link--a">DIV 3</a></li>
        </ul>
    </nav>
Enter fullscreen mode Exit fullscreen mode

But when we click on the element it takes us to the element with the id provided in href. This is how a normal scrolling effect looks like 👇🏻

ezgif.com-gif-maker.gif

So what can we do for a smooth scrolling effect ?

HTML CODE

    <nav class="navbar" id="nav--bar">
        <ul>
            <li><a href="#1" class="link--a">DIV 1</a></li>
            <li><a href="#2" class="link--a">DIV 2</a></li>
            <li><a href="#3" class="link--a">DIV 3</a></li>
        </ul>
    </nav>
    <section id="1">
        <div class="div div--1">This is DIV 1</div>
    </section>
    <section id="2">
        <div class="div div--2">This is DIV 2</div>
    </section>
    <section id="3">
        <div class="div div--3">This is DIV 3</div>
    </section>

    <script src="script.js"></script>
Enter fullscreen mode Exit fullscreen mode

CSS CODE

This code depends on personal choices as this will affect the design part!

body {
  margin: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  align-items: center;
}
.div--1 {
  background-color: rgb(0, 132, 255);
}
.div--2 {
  background-color: rgb(255, 136, 0);
}
.div--3 {
  background-color: rgb(255, 0, 242);
}
.navbar ul {
  display: flex;
  justify-content: space-around;
  background-color: rgb(179, 230, 245);
  list-style: none;
  padding: 1.5em;
  border-radius: 12px;
  border: 1px solid black;
}
.navbar ul li a {
  background-color: yellow;
  padding: 1em;
  border-radius: 12px;
  border: 1px solid black;
  text-decoration: none;
}
.navbar ul li:hover {
  background-color: orangered;
  cursor: pointer;
}
.navbar {
  width: 90%;
}
section {
  width: 75%;
}
.div {
  margin: 1em;
  border-radius: 12px;
  border: 1px solid black;
  font-size: 5em;
  height: 80vh;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

Enter fullscreen mode Exit fullscreen mode

JS CODE

The Most Important Part !!

document.getElementById('nav--bar').addEventListener('click', function (e) {
    e.preventDefault();
    const target = e.target;
    if (target.classList.contains('link--a')) {
        const id = target.getAttribute('href').slice(1);
        document.getElementById(id).scrollIntoView({ behavior: 'smooth' });
    }
});
Enter fullscreen mode Exit fullscreen mode

Now let's Focus on JS code and understand how each line works!

  1. We are having this block of code at the top. This says that the document targets the element who is having the id "nav-bar" and adds an event listener on it which will listen to the event (click) on it. And if a click happens on that event then call the function which is having parameter e which will represent the event.
document.getElementById('nav--bar').addEventListener('click', function (e) {
});
Enter fullscreen mode Exit fullscreen mode

2.The prevent Default function will prevent the auto-scrolling due to the anchor tag. And such help us to implement smooth scrolling. In the target variable, we will store the location at which point the click event happened so we can know that exactly on which link the user clicked.

e.preventDefault();
const target = e.target;
Enter fullscreen mode Exit fullscreen mode

3.This if loop will help us to target only those clicks which are on elements having class "link--a".

if (target.classList.contains('link--a')) {
}
Enter fullscreen mode Exit fullscreen mode

4.In variable id we will be saving the value given in href attribute of the element where the event (click) occurred. As we have given "#1" in href we need to cut the '#' and store the remaining value.

const id = target.getAttribute('href').slice(1);
Enter fullscreen mode Exit fullscreen mode

5.This will now target the element which is having the id the same as the value stored in the id variable and apply the "scrollIntoView" method on it with smooth behavior as we mentioned in it.

document.getElementById(id).scrollIntoView({ behavior: 'smooth' });
Enter fullscreen mode Exit fullscreen mode

This will give us output like this 👇🏻

ezgif.com-gif-maker(1).gif

Great 🎉 We have successfully implemented the smooth scroll!

You can check the difference between both these effects will give professional look to your website!

Normal Smooth Scroll
ezgif.com-gif-maker.gif ezgif.com-gif-maker(1).gif

STAY TUNED FOR MORE 😄
GET CONNECTED WITH ME

Twitter
LinkedIn

Top comments (6)

Collapse
 
link2twenty profile image
Andrew Bone

You could also use scroll-behavior which has pretty good support and is just CSS.

html {
  scroll-behavior: smooth;
}
Enter fullscreen mode Exit fullscreen mode

Here's your demo with no JavaScript.

Collapse
 
eshimischi profile image
eshimischi

Safari doesn't support it tho without extra js polyfills

Collapse
 
rohank_2502 profile image
Rohan Kulkarni

Thanks was not knowing this

Collapse
 
gagan_codewithme profile image
Gagandeep Singh

If we have a fixed navbar on the webpage. and we use -

html {
scroll-behavior: smooth;
}

this will work but that height of fixed navbar takes over some portion of the page view. how can I fix it? Suggest something.

I also tried using scrollTo() using javascript but it needs further more optimization to work flawlessly.

here's the code -
`const hamburgerClick = document.getElementById("navbar-toggle");

const navLinks = [...document.querySelectorAll(".nav-links")]; // stored the NodeList into array format using "..." operator
const coverSection = document.querySelector(".cover-style-toggle");

// navbar options
const navSection = document.querySelector("#nav-section");
const techSection = document.querySelector("#tech-section");
const projSection = document.querySelector("#project-section");
const footerSection = document.querySelector('#footer-section');

// sections
const navBar = document.querySelector('.header');
const resume = document.querySelector(".resume-section");
const techStack = document.querySelector(".tech-grid");
const project = document.querySelector(".project-sec");
const footer = document.querySelector(".footer");

const handleNavToggle = function(){
navLinks.map((ele)=> {
ele.classList.toggle('active');
});
console.log(coverSection);
coverSection.classList.toggle('cover-active');
console.log('clicked');
}
hamburgerClick.addEventListener('click', handleNavToggle);

function sectionScroll(section) {
let coordVal = section.getBoundingClientRect();
// console.log(coordVal);
console.log(navBar.getBoundingClientRect());
let navBarCoord = navBar.getBoundingClientRect();
scrollTo({left:coordVal.x,top :(coordVal.y - navBarCoord.height), behavior:"smooth"});
}

navSection.addEventListener("click", function () {
sectionScroll(resume);
});
techSection.addEventListener("click",function(){
sectionScroll(techStack);
});
projSection.addEventListener("click",function(){
sectionScroll(project);
});
footerSection.addEventListener("click", function () {
sectionScroll(footer);
})`

Collapse
 
przemek profile image
Przemyslaw Michalak

What happened to old good classic:

html {
  scroll-behavior: smooth;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
rohank_2502 profile image
Rohan Kulkarni

Thanks was not knowing this