Snap Scroll in CSS

Portrait of TomTom31-08-2020

I know my scroll!

Implementing scroll behavior in your web app wouldn't tempt you to think about it much further than: this container's content might have overflow, so let's just do this:

/* Vertical axis */
.container {
  overflow-y: scroll;
}

/* Horizontal axis */
.container {
  overflow-x: scroll;
}

Not much to see here. But thinking about it a second time, we might recognize that in specific use cases, this implementation doesn't yield the best usability.

Time to improve

Specifically, your container might show a list of cards, e.g. to be aligned on the horizontal axis. With the implementation above, we would pick the "overflow-x: scroll" property and would be good to go. This works well in an environment where there's much width available, as scrolling through the horizontal list always shows at least some elements.

Yet when using the container on a narrower device, e.g. smartphone, the user might only see one element of the list at a time, as due to the width-constraint no more than one card can be shown at once. This leads to the following situation: a user starts scrolling from left to right, but needs to take special care of stopping the scroll (releasing the touch) when the card is best visible, e.g. centered, in the container.

This can lead to frustrating user experiences, as positioning any element manually in a precise manner is an interaction overhead we want to avoid at any cost. Scroll-snap to the rescue!

It's snap time

With CSS' scroll-snap-type, we can tell our favorite layout engine of choice that, based on the position of the scroll when the scroll ends, the container snaps the element either to the left, right or center - according to our implementation - and therefore perfectly aligning it, freeing the use of worrying about manual precise placement. The properties look like this (example from developer.google.com, link below):

<style>
#gallery {
  scroll-snap-type: x mandatory;
  overflow-x: scroll;
  display: flex;
}

#gallery img {
   scroll-snap-align: center;
}
</style>

<div id="gallery">
  <img src="cat.jpg">
  <img src="dog.jpg">
  <img src="another_cute_animal.jpg">
</div>

As you can see, implementing scroll comes practically for free, as we really only need to take care of two things:

  • scroll-snap-type: used on the container to define the axis + snap behavior
  • scroll-snap-align: used on the children to define if the element should be snapped to the left, right or center

And that's about it! Implementing a snappy scroll in CSS is dead simple and can greatly enhance your app's usability, especially in narrow environments such as smartphones. I've linked more detailed examples below and hope you've enjoyed learning something new today!

- Tom

👉 Examples by Google

👉 MDN overflow