How to Create Native Smooth Scrolling with JavaScript (or CSS)
A few days ago, I was rendering out a list in Vue that needed some smooth scrolling.
Naturally, I turned to a JavaScript solution, but lo and behold, CSS had me covered.
For simplicity’s sake, suppose we have a navbar that brings us to another section of a webpage.
<nav>
<ul>
<a href="#one"><li>One</li></a>
<a href="#two"><li>Two</li></a>
<a href="#three"><li>Three</li></a>
</ul>
</nav>
We also have content to render out.
<div class="content">
<div id="one"><h1>One</h1></div>
<div id="two"><h1>Two</h1></div>
<div id="three"><h1>Three</h1></div>
</div>
Smooth Scrolling using CSS#
In order to demo smooth scrolling, we need to style each page accordingly:
.content div {
width: 100%;
height: 100vh;
text-align: center;
}
nav {
position: fixed;
}
#one {
background: #fff;
}
#two {
background: #e0e0e0;
}
#three {
background: #fff;
}
The secret here is to add scroll-behavior: smooth;
to the <html>
element.
html {
scroll-behavior: smooth;
}
This will give us a basic template for smooth scrolling pages using a navbar. We can also isolate smooth scrolling to different sections of the webpage. It just depends on where you put the scroll-behavior
attribute.
Smooth Scrolling using JavaScript#
We can also smooth scroll in JavaScript.
If we know the exact location of the element we want to scroll to, we can scroll to a specific section of the page by using window.scroll()
and modifying top
.
window.scroll({
top: 4000,
left: 0,
behavior: "smooth",
});
If we know the offset from the current location, we can use window.scrollBy()
and, once again, modify top
.
window.scrollBy({
top: 200,
left: 0,
behavior: "smooth",
});
I find myself mostly using this last option, where we scroll to a specific element with a combination of document.querySelector()
and scrollIntoView()
.
document.querySelector("#one").scrollIntoView({
behavior: "smooth",
});