Two Smooth-Scrolling Techniques
Pure CSS and pure JavaScript techniques to implement smooth scrolling.
Here is a starter file to make following this guide easier. Click on the 'Edit on Codepen' text on the top-right of the embed below to open the file in a separate tab.
Using Pure CSS
To implement smooth scrolling via pure CSS, we make use of anchor tags and ID attributes.
When an anchor tag is clicked, the browser directs us to the URL specified in its href
attribute. The URL can point to both external sites as well as specific sections of the web page(internal linking).
We first give IDs to elements that we want to scroll into and mention those IDs in the href
attributes of the anchor tags. We prefix the IDs with the # symbol that lets the browser know that the link is from the current page.
<nav>
<ul class="links">
<li><a href="#sec-1">section 1</a></li>
<li><a href="#sec-2">section 2</a></li>
<li><a href="#sec-3">section 3</a></li>
<li><a href="#sec-4">section 4</a></li>
<li><a href="#sec-5">section 5</a></li>
</ul>
</nav>
Doing so enables click-to-scroll, i.e. clicking on any of the anchor tags will now scroll the page to the element containing the ID specified in their href
attributes. But this scroll is a jump-scroll, i.e. the page directly jumps to the appropriate section. To implement a smooth scroll, we modify the scroll behavior in the CSS.
We set the scroll-behavior
property to smooth
for the element or container that needs the smooth-scrolling behavior. In most cases, the entire web page scrolls, so the property will be set for the html
element. But in the starter code that we're working on, scrolling happens inside the main
tag which has a fixed height and width. So the property is set for that element.
main {
height: 100%;
margin: 20px;
overflow-y: scroll;
scroll-behavior: smooth;
}
Clicking on the anchor tags now will scroll the view smoothly into the appropriate sections
Using JavaScript
We can get rid of the anchor tags when taking the JavaScript route, as it is then possible to trigger a scroll from any element.
We still need an identifier to know which element to scroll into, and we can make use of custom data attributes for that.
Set a custom attribute called target
for each of the nav items with values ranging from 1 to 5. You'll understand why in a moment.
<nav>
<ul class="links">
<li data-target="1">section 1</li>
<li data-target="2">section 2</li>
<li data-target="3">section 3</li>
<li data-target="4">section 4</li>
<li data-target="5">section 5</li>
</ul>
</nav>
Here's how we'll implement smooth scrolling with JS
- Add a click event listener to the list items. I'm adding one listener on the
ul
tag and listening to the click events on all the list items via event delegation - In the click handler, retrieve the target information from the clicked element
- Select the element corresponding to the retrieved target information
- use
element.scrollIntoView({behavior: 'smooth'})
to smoothly scroll into the element
const navLinks = document.querySelector('.links');
function navClickHandler(event) {
const clicked = event.target.closest('li');
const targetId = clicked.dataset.target;
const targetEl = document.querySelector(`#sec-${targetId}`);
targetEl.scrollIntoView({behavior: 'smooth'})
}
navLinks.addEventListener('click', navClickHandler)
Did you find this article valuable?
Support Abin John by becoming a sponsor. Any amount is appreciated!