How to add smooth scrolling to every anchor element on a page
Ever needed a smooth scroll when clicking on a
elements? I am here to help!
TL;DR: code snippet.
Overview
We need for a page to scroll smoothly when clicking on anchor that leads to some element with given id. So we need our anchor element, our target element and a function to scroll a page up ⬆️ (or down ⬇️) to target element. What a relief — we can achive that with vanilla JavaScript using built-in functions!
Theory
Retrieving anchors
Since only anchors with set href
attribute as id
of some other element scrolls page to that other element, we can only perform smooth scrolling with that anchors. How can we find them? They have something in common: that being href
attribute starting with ‘#’, so we can easily collect them using “attribute starting with” selector. Our attribute will be ‘href’ and it must start with a ‘#’: document.querySelectorAll('[href^=#]')
. More on this function on MDN.
Iterating over NodeList
Some ways you can iterate over NodeList are described on corresponding MDN page. I decided to use Object
’s built-in method entries
to get an array of pairs [key, value]
and iterate over it with forEach()
Array
method. In forEach()
, thanks to developing JavaScript, we can extract that [key, value]
values from pair: [key, value] = [ 'iamkey', 'iamvalue' ]
.
Adding events
This one is simple: add on click event that scrolls us to target element. Doing that we will override default behavior, so I recommend adding event.preventDefault()
to callback.
JavaScript has built-in function that will scroll document to desired position measured from top of the document in pixels. To add behavior: 'smooth’
we must pass an options
object with set top
and behavior
values.
How to get target element position
Firstly, we need to get that element. I am using querySelector()
function to avoid storing href
attribute and operating on it with slice method.
To get element’s relative position from top of the document, we can getBoundingClientRect()
of that element and retrieve top
value. To add some space above for better readability, better scroll to just before the target element (let it be 50 pixels). Now we can smoothly scroll up to desired element!
Code snippet.