DEV Community

Cover image for Smooth Scrolling with JS
Shubham Tiwari
Shubham Tiwari

Posted on

Smooth Scrolling with JS

Hello Everyone today I will show how you can create smooth scrolling with Javascript as well as with CSS.

Let's get started...

What we are going to create

With CSS only

HTML -

<header>
  <ul class="nav">
    <li><a class="nav_link" href="#section1">Section 1</a></li>
    <li><a class="nav_link" href="#section2">Section 2</a></li>
    <li><a class="nav_link" href="#section3">Section 3</a></li>
    <li><a class="nav_link" href="#section4">Section 4</a></li>
    <li><a class="nav_link" href="#section5">Section 5</a></li>
  </ul>
</header>

<main>
  <section id="section1">This is Section 1</section>
  <section id="section2">This is Section 2</section>
  <section id="section3">This is Section 3</section>
  <section id="section4">This is Section 4</section>
  <section id="section5">This is Section 5</section>
</main>
Enter fullscreen mode Exit fullscreen mode
  • I have created a simple Header with Navbar and main with 5 section.
  • The href attribute of the anchor tag and id attribute of section tag are same, it means when we click on any anchor tag, it will directly jump to the section it is connected with. But it will jump to that section immediately like it just teleported there.
*{
  margin:0;
  paddin:0;
  box-sizing:border-box;
  scroll-behavior: smooth;
}
ul{
  list-style:none;
}
a {
  text-decoration:none;
}

.nav{
  position:fixed;
  top:0;
  min-width:100%;
  padding:10px;
  display:flex;
  justify-content:center;
  gap:1rem;
  flex-wrap:wrap;
  background-color:rebeccapurple;
}
.nav_link {
  color:white;
}

section{
  height:100vh;
  display:grid;
  place-items:center;
  font-size:2rem;
}
#section1{
  background:crimson;
  color:white;
}
#section2{
  background:violet;
}
#section3{
  background:lime;
}
#section4{
  background:cyan;
}
#section5{
  background:rgb(0,0,0,0.8);
  color:white;
}
Enter fullscreen mode Exit fullscreen mode
  • I just styled the navbar and sections with some CSS
  • At the top, I have used scroll-behavior: smooth, this will make that auto-scrolling to a particular section smooth when we click on any link that scrolls the view to that section.

Browser Support

Image description

With Javascript

  • HTML and CSS part will be the same as above ( Just remove that scroll-behavior:smooth property from CSS code).

JavaScript

  • Older Way
const navbar = document.querySelector(".nav");

navbar.addEventListener("click", (e) => {
  e.preventDefault();
  const target = e.target;
  if (target.classList.contains("nav_link")) {
    const id = e.target.getAttribute("href");
    //Older browser Support
      const section = 
         document.querySelector(id).getBoundingClientRect();

      window.scrollTo({
      left:section.left + window.pageXOffset,
      top:section.top + window.pageYOffset,
      behavior:"smooth"
    })
  }
});
Enter fullscreen mode Exit fullscreen mode
  • Using event target, checking if the link which is clicked has a class name "nav_link", if it does, then get the href attribute value of that link.
  • By passing this href attribute value as id in the querySelector(), we will get the section which is connected to this link ( Example - href="#section1" in anchor tag and id="section1" in section tag), querySelector will recieve the id directly like querySelector("#section1")
  • What it is doing, is just calculating the top and left value of the section using getBoundingClientRect() method and bahavior:smooth will make the scrolling smooth. There is better method of doing this so, you can just not go in depth for this one.

  • Modern Way

const navbar = document.querySelector(".nav");

navbar.addEventListener("click", (e) => {
  e.preventDefault();
  const target = e.target;
  if (target.classList.contains("nav_link")) {
    const id = e.target.getAttribute("href");
    document.querySelector(id).scrollIntoView({ behavior: "smooth" });
  }
});

Enter fullscreen mode Exit fullscreen mode
  • We have another method called "scrollIntoView", we just need to apply this method to the section container with bahavior:"smooth" parameter and it will make the scrolling smooth.

Browser support for this

Image description

THANK YOU FOR CHECKING THIS POST
You can contact me on -
Instagram - https://www.instagram.com/supremacism__shubh/
LinkedIn - https://www.linkedin.com/in/shubham-tiwari-b7544b193/
Email - shubhmtiwri00@gmail.com

^^You can help me with some donation at the link below Thank youšŸ‘‡šŸ‘‡ ^^
ā˜• --> https://www.buymeacoffee.com/waaduheck <--

Also check these posts as well
https://dev.to/shubhamtiwari909/css-iswherehas-and-not-2afd

https://dev.to/shubhamtiwari909/theme-changer-with-html-and-css-only-4144

https://dev.to/shubhamtiwari909/swiperjs-3802

https://dev.to/shubhamtiwari909/going-deep-in-array-sort-js-2n90

Latest comments (3)

Collapse
 
raibtoffoletto profile image
RaĆ­ B. Toffoletto

How would you handle people that have the css prefers-reduced-motion set to reduce!? Would nice to check it before applying the smooth scroll:

window.matchMedia("(prefers-reduced-motion: reduce)")

in case it matches I would use the normal jump behavior.

btw: not sure why but on chrome/ios this sandbox isn't working šŸ˜¢

Collapse
 
shubhamtiwari909 profile image
Shubham Tiwari

Maybe the integration of Codepen is not supported in iOS
You can check the sandbox here
codepen.io/shubhamtiwari909/pen/XW...

Collapse
 
shubhamtiwari909 profile image
Shubham Tiwari

I am not sure about prefers-reduced-motion, but i think we can fix that with media query of prefers-reduced-motion, enabling scroll-behavior:smooth there
If it is not correct then i have to read about it
Btw thank you for mentioning this thing