HTML has always had the ability to jump to locations on a page, provided the target element has an id
attribute, via a technique known as anchor links.
However, this movement is instantaneous. For the sake of appearance, a site's design sometimes calls for a smooth or slowed scroll to a point on a page.
Historically, this was achieved with JQuery, but it's overkill to load a framework just for one technique. Modern JavaScript provides a more efficient, native alternative, in the form of the window.scrollTo
method.
A standard anchor link is used as the basis of the technique: that way, if the new smooth scroll code doesn’t work for any reason, the page will still go to the targeted location.
<a href="#destination">Click me: I’m <em>smoooooth</em>.</a>
…
<p id="destination">This is the target, further down the page.
Two Sides of Scrolling
Somewhat confusingly, the Smooth Scrolling API is implemented in two ways: once as a CSS property, and again in JavaScript. Adding to this confusion is the fact that some browsers support the API, while others do not.
For the CSS method, the element that will be smooth-scrolled (frequently, but not exclusively, the body
) needs to have a scroll-behavior
of smooth
applied in CSS:
body {
scroll-behavior: smooth;
}
This is enough to make the effect work in the current version of Firefox, but browsers like Chrome need more work, as of this writing.
The JavaScript Side
Browsers that do not support the scroll-behavior
CSS property will need to use the JavaScript API, and most of those will need a polyfill: I would recommend Dustan Kasten’s smoothscroll, although there are many other possibilities.
Let’s imagine that we have a <nav>
section with links:
<nav>
<a href="#profile">Profile</a>
<a href="#writing">Writing</a>
<a href="#presentations">Presentations</a>
<a href="#recentwork">Recent Work</a>
</nav>
These links will go to <section>
elements with matching id
attribute values:
<section id="profile">
<h2>Profile</h2>
</section>
<section id="writing">
<h2>Writing</h2>
</section>
The JavaScript, added to the bottom so it doesn’t block execution on the rest of the page. I’ve expanded the code slightly from the promised five lines for clarity:
var anchorLinks = document.getElementsByTagName("nav")[0];
if (window.scrollTo) {
anchorLinks.addEventListener("click",
function(e) {
dest = document.getElementById(e.target.href.split("#")[1]);
window.scroll({top: dest.offsetTop, behavior: 'smooth'});
})}
The code uses event bubbling to listen to a click inside the nav
element scrollTo
method to get there instead, smoothed by the earlier CSS declaration. scrollTo
takes a behavior
and top
argument, with an optional left
argument, the latter two taking the coordinate information of the destimation.
In comparison to a framework, this syntax is far simpler; the one downside is that it doesn’t allow the designer to change the timing function or scroll movement, to avoid abuses.
Conclusion
This technique is often combined with elements that are are “sticky”, i.e. elements that scroll with the page until they reach the top of the viewport, where they “stick” in place, which I cover in another article.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/pJVVBx