An Introduction to CSS Scroll Snapping

I recently watched a talk on YouTube from the Chrome Dev Summit called “Next generation web styling,” and scroll snap was the first module they covered, which I thought was pretty cool. You should check out the video to get their overview of scroll snapping, and for the other awesome CSS features they discuss throughout.

What is scroll snapping?

Scroll snapping is precisely what it sounds like. It forces the user to “snap” to certain points on the page as they scroll. It’s nice if you want to guide users through certain points of the page. It is already pretty widely supported in major browsers. When I looked at caniuse it was covering a little over 84% of users.

Animated GIF demonstrating the snap effect of setting an element to mandatory scroll.

Although it has been around for some time, the scroll snap module was recently updated. With support now in Firefox, Chrome, and even Edge. With mobile almost fully supported too. What is even better is that it gracefully degrades, so if a browser doesn’t support it, the native scrolling that we all know and love kicks back in.

How to use scroll snapping?

It’s pretty easy to get started with this feature. In the past, developers have had to use JavaScript to get this type of scrolling behavior, but now we can manage scroll snapping directly in CSS with only a small amount of code.

Step 1

First, you set a parent container to have a scroll snap type, which can either be vertical or horizontal scrolling. The snap direction is represented by setting the value to either x or y. You can also set it to be mandatory scrolling or proximity scrolling, which determines if the user is forced to rest at a snap point or not.


/** This will set the html document to scroll horizontally and will 
    be mandatory for users to snap to each point. **/

html {
	scroll-snap-type: y mandatory;
}

Step Two

At the moment, no behavior changes. For things to work, you also need to give the children a scroll-snap-align. The property can take the values of start, end, and center. When the scroll snaps, should it snap to the start (top), the end (bottom), or the center of the element in question?


/** This will require the snap to be set to the start of the html element **/

section {
    scroll-snap-align: start;
}

Example Time

In the CodePen example below, I have set the entire HTML element to be scroll-snap-type: y mandatory. This means that the document scrolls horizontally, and the user is required (mandatory) to snap to each point.

See the Pen
Scroll Snapping
by Christina Reilly (@creillz)
on CodePen.

Additional Properties

There are a few more properties available to us in addition to the two discussed above to customize the scrolling experience even more. Including setting padding and margin on the parent container. You can view the exhaustive list on Mozilla.

Final Thoughts

Setting scroll snap to mandatory does provide the most consistent experience over proximity; however, there are certain instances where this should not be used. Imagine an example where an element inside a scrolling parent container is taller than the viewport. If that is set to mandatory, it will always snap to the top or bottom, making it impossible to scroll to the middle part of the section, which might cause a user not to see all of the information. If we go back to our CodePen example and add a bunch of paragraph text to each element, it would be highly annoying to the user to try and see all of the text without holding onto their mouse.

Overall, I think this a nice feature, but we should not overuse this module. I believe this can be a nice enhancement for user experience in the right situation. I’m thinking image galleries scaling down from desktop to mobile would be a great use case for this. As people continue to use this module, I’m confident we will discover creative and accessible ways to implement scroll snapping.