March 4, 2020 How to animate scrolling to anchor links with one line of CSS

This week, we’ve been looking at how to use modern CSS to do things that used to require a bunch of custom JavaScript.

On Monday, we learned how to make a sticky header with the position: sticky property. And yesterday, we looked at how to prevent anchor links from scrolling behind it with the scroll-margin-top property.

Today, we’re going to learn how to animate scrolling to anchor links with one line of CSS.

The scroll-behavior property

The scroll-behavior property tells the browser how to handle scrolling to anchor links within an element.

The default value, auto , does a hard jump like you’re used to. A value of scroll tells the browser to animate scrolling. There’s no way to specify easing, but it ties into the browser’s refresh rate to give you silky smooth animations.

/** * Enable smooth scrolling on the whole document */ html { scroll-behavior : smooth ; }

Here’s a demo.

I typically enable it on the whole html document, but you can restrict it to specific elements if you want.

/** * Enable smooth scrolling on the #be-cool element */ # be-cool { scroll-behavior : smooth ; }

Accessibility concerns

Animations can cause issues for users who suffer from motion sickness and other conditions.

Fortunately, Windows, macOs, iOS, and Android all provide a way for users to specify that they prefer reduced motion. And all modern browsers (but not IE) provide a way to check for that setting in both CSS and JavaScript.

When using scroll-behavior , you should add a @media check for preders-reduced-motion: reduce , and revert to the default auto .

/** * Disable smooth scrolling when users have prefers-reduced-motion enabled */ @ media screen and ( prefers-reduced-motion : reduce ) { html { scroll-behavior : auto ; } }

This prevents animated scrolling when users have specified that they’d prefer reduced motion.

Browser support

The scroll-behavior property works in most modern browsers. It does not work in Safari or mobile Safari. It also has no IE support.

This is a great progressively-enhanced feature, though.