scroll-behavior

Scroll to the Future

This is an interesting read on the current state of scrollbars and how to control their behavior across operating systems and browsers. The post also highlights a bunch of stuff I didn’t know about, like Element.scrollIntoView() and the scroll-behavior CSS property.

My favorite part of all though? It has to be this bit:

In the modern web, relying heavily on custom JavaScript to achieve identical behavior for all clients is no longer justified: the whole idea of “cross-browser compatibility” is becoming a thing of the past with more CSS properties and DOM API methods making their way into standard browser implementations.

In our opinion, Progressive Enhancement is the best approach to follow when implementing non-trivial scrolling in your web projects.

Make sure you can provide the best possible minimal, but universally supported UX, and then improve with modern browser features in mind.

Speaking of the cross-browser behavior of scrollbars, Louis Hoebregts also has a new post that notes how browsers do not include the scrollbar when dealing with vw units and he provides a nice way of handling it with CSS custom properties.

Smooth Scrolling

Hey! Before you go too far down the rabbit hole of JavaScript-based smooth scrolling, know that there is a native CSS feature for this: scroll-behavior.

html {
  scroll-behavior: smooth;
}

And before you reach for a library like jQuery to help, there is also a native JavaScript version of smooth scrolling, like this:

// Scroll to specific values
// scrollTo is the same
window.scroll({
  top: 2500, 
  left: 0, 
  behavior: 'smooth' <pre rel="HTML"><code markup="tt" class="language-markup">
});

// Scroll certain amounts from current position 
window.scrollBy({ 
  top: 100, // could be negative value
  left: 0, 
  behavior: 'smooth' 
});

// Scroll to a certain element
document.querySelector('.hello').scrollIntoView({ 
  behavior: 'smooth' 
});

Dustan Kasten has a polyfill for this. And you'd probably only reach for this if you were doing something with scrolling the page that couldn't be done with #target jump links and CSS.

Accessibility of Smooth Scrolling

Whatever technology you use for smooth scrolling, accessibility is a concern. For example, if you click a #hash link, the native behavior is for the browser to change focus to the element matching that ID. The page may scroll, but the scrolling is a side effect of the focus changing.

If you override the default focus-changing behavior (which you have to, to prevent instant scrolling and enable smooth scrolling), you need to handle the focus-changing yourself.

Heather Migliorisi wrote about this, with code solutions, in Smooth Scrolling and Accessibility.

Smooth Scroll with jQuery

jQuery can also do this. Here's the code to perform a smooth page scroll to an anchor on the same page. It has some logic built in to identify those jump links, and not target other links.

// Select all links with hashes
$('a[href*="#"]')
  // Remove links that don't actually link to anything
  .not('[href="#"]')
  .not('[href="#0"]')
  .click(function(event) {
    // On-page links
    if (
      location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') 
      && 
      location.hostname == this.hostname
    ) {
      // Figure out element to scroll to
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
      // Does a scroll target exist?
      if (target.length) {
        // Only prevent default if animation is actually gonna happen
        event.preventDefault();
        $('html, body').animate({
          scrollTop: target.offset().top
        }, 1000, function() {
          // Callback after animation
          // Must change focus!
          var $target = $(target);
          $target.focus();
          if ($target.is(":focus")) { // Checking if the target was focused
            return false;
          } else {
            $target.attr('tabindex','-1'); // Adding tabindex for elements not focusable
            $target.focus(); // Set focus again
          };
        });
      }
    }
  });

See the Pen Smooth Page Scrolling in jQuery by Chris Coyier (@chriscoyier) on CodePen.

If you've used this code and you're all like HEY WHAT'S WITH THE BLUE OUTLINES?!, read the stuff about accessibility above.

icon-anchoricon-closeicon-emailicon-linkicon-logo-staricon-menuicon-nav-guideicon-searchicon-staricon-tag