Explain Codes LogoExplain Codes Logo

Smooth scrolling when clicking an anchor link

html
responsive-design
performance
best-practices
Nikita BarsukovbyNikita BarsukovยทSep 30, 2024
โšกTLDR

First up, scrollIntoView and behavior: 'smooth' is the quickest way to achieve smooth scrolling in JavaScript.

// All aboard the scroll train! ๐Ÿš‚ document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function(e) { e.preventDefault(); // Stop! Anchor time. ๐Ÿ›‘ const target = document.querySelector(this.getAttribute('href')); target?.scrollIntoView({ behavior: 'smooth' }); // Ride to destination. ๐ŸŽข }); });

This script attaches a click event to all anchor links that point to an id on the page. It then prevents the default jumping motion and replaces it with a buttery smooth scroll to the link's target.

Smooth experience with CSS

So you love CSS? Go turbo and activate native smooth scrolling:

html { scroll-behavior: smooth; }

If your page rocks a sticky header, use scroll-padding-top:

body { scroll-padding-top: 70px; // size matches your header height }

Backward compatibility: A JS answer for older browsers

For elder browsers, like the infamous Internet Explorer, you can use jQuery's animate:

// Who you gonna call? jQuery! $('a[href^="#"]').on('click', function(e) { e.preventDefault(); // No jumping kangaroo here. ๐Ÿฆ˜ const target = $($(this).attr('href')); $('html, body').animate({ scrollTop: (target.offset().top) - 50 // Room for the header }, 1000, function() { window.location.hash = target.selector; // Updating the URL }); });

Splendid practice here is to cache your selectors for a first-class performance:

// The cool kids store selectors in a variable, and so can you. ๐Ÿ†’ const $anchors = $('a[href^="#"]'); $anchors.on('click', function(e) { // Implement event handler });

Playing nice with browsers

Before choosing a scroll method, check if it's well-supported:

  • scroll-behavior: smooth; plays well with modern browsers.
  • scrollIntoView is a_scripts_bases runner with { behavior: 'smooth' }.
  • window.scroll or window.scrollBy can be used with { behavior: 'smooth' } for a premium tuning.

Pro tips to level up your smooth scrolling

Accurate URL tracking with history.pushState

To update the URL without reloading a page, sprinkle in history.pushState:

// Shhh. It's a sneaky URL update. ๐Ÿ•ต๏ธโ€โ™€๏ธ window.history.pushState(null, null, target);

Include this in the scrollTo event listener or jQuery's animate callback for the magic.

Accounting for fixed headers

Got a fixed header? Adjust the scroll position accordingly:

// Header? What header? ๐Ÿคทโ€โ™€๏ธ const headerHeight = document.querySelector('.fixed-header').offsetHeight; target.scrollIntoView({ behavior: 'smooth', block: 'start' }); window.scrollBy(0, -headerHeight);

Reusable scroll functionality: Save the trees

Keep your work DRY (Don't Repeat Yourself) by bundling your scroll function:

// Recycle, reuse, reduce. โ™ป๏ธ function smoothScrollTo(selector) { const target = document.querySelector(selector); if (target) target.scrollIntoView({ behavior: 'smooth' }); }

With this function, you can call smooth scrolling whenever you need it.

Code accessibility: Minding your Ps and Qs

Smooth scrolling isn't just ice cream for the eyes ๐Ÿฆ; it should also enhance navigation and accessibility:

  • Test with keyboard navigation and screen readers.
  • Be mindful of scroll-jacking. Smooth scrolling should make the UX better, not worse.