CSS Smooth Scrolling
Tags: css, javascript, html, webdev
Published: 2019-02-14 08:31:18

---
title: CSS Smooth Scrolling
published: true
description: CSS is super powerful, before building something new it's a good idea to take a moment and see if something can be built with CSS instead of JavaScript
canonical_url: https://pqina.nl/blog/css-smooth-scrolling/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/r6ef2pcjofs6jd1mz7m0.jpeg
tags: css, javascript, html, webdev
---

Last year, while building the [FilePond product page](https://pqina.nl/filepond/) I stumbled upon the scrollIntoView API. It's a handy method to instruct the browser to scroll an element into the viewport.

> This article was originally published on [my personal blog](https://pqina.nl/blog/css-smooth-scrolling/)

The [`scrollIntoView`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) API can be instructed to animate the scrolling part by adding the `behavior` property on the `scrollIntoViewOption` object. 

```js
element.scrollIntoView({ behavior: 'smooth' });
```

I quickly jumped on my JavaScript horse and wrote a tiny script to automatically detect clicks on anchors so the browser would animate the jump towards the anchor target. This jump can be really disorienting, so animating this process would improve the user experience quite a bit.

[scrollIntoViewOption currently only works on Firefox and Chrome](https://caniuse.com/#feat=css-scroll-behavior).

{% codepen https://codepen.io/rikschennink/pen/ZjBGda default-tab=js,result %}

![Noice!](https://thepracticaldev.s3.amazonaws.com/i/h9rjdbd131sseypv7n1y.gif)

I [posted it on Twitter](https://twitter.com/rikschennink/status/1019960938194259976) and called it a day.

Then, [Hans Spieß points out that this can also be done with CSS](https://twitter.com/hans_/status/1020081742277902336), WHAT!?

Turns out there's a [`scroll-behavior`](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior) CSS property that we can set to `smooth`, it's literally that literal. It's almost like `awesome: yes-please`. We can set the `scroll-behavior` property to the container we want to exhibit smooth scroll behavior and we're done.

I created [a new demo using only CSS](https://codepen.io/rikschennink/details/NBBZWO).

![Smooth scroll comparison](https://thepracticaldev.s3.amazonaws.com/i/qci4smo6xj0fazxwuz9t.gif)

Before we go nuts and apply this to all our sites, there are a couple of things we need to keep in mind.


### Scroll distance matters

If there is a lot of distance to travel, Firefox will skip content to keep the scroll time-limited, while Chrome has a max velocity and will just take its time to get to the target.

[![Long distance scroll comparison](https://thepracticaldev.s3.amazonaws.com/i/2t28rviy1nrfjbepbm81.gif)](https://codepen.io/rikschennink/details/QBZByx)

We could use [Smart CSS](https://dev.to/rikschennink/applying-styles-based-on-the-user-scroll-position-with-smart-css-5c) to detect long pages and conditionally apply the smooth scroll style.


### Accessibility

People might get motion sickness when watching the animation. To circumvent this you can wrap the CSS property in a [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion) media query. Unfortunately, Chrome does not support this. Safari supports it, but Safari doesn't support smooth scrolling.

```css
.my-smooth-container {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  .my-smooth-container {
    scroll-behavior: auto;
  }
}
```

## Conclusion

When deciding on a new functionality we shouldn't reach out to JavaScript immediately. We should do a quick search first to find out if it can be done with CSS as well. The `scroll-behavior` property can be a nice UX improvement, do make sure you disable it on very long pages and offer an option to disable it to keep your pages accessible.