Scroll snapping explained

Have you ever tried to snap your page’s contents after scrolling? There are many JavaScript libraries out there providing this functionality. Here are a few examples:

As this is a common use case related to page layout and behavior, the W3C has published a pure CSS approach to scroll snapping.

CSS scroll snapping, (available since July’s Firefox 39 release), allows you to control where to stop on an overflowing element when it’s scrolled. This lets you section your page into logical divisions and thus create smoother, easier-to-interact-with user interfaces. Touch devices in particular benefit from this feature, where it is easier for people to pan through pages instead of tapping through hierarchical structures.

Image gallery

Image galleries are surely the most common use case for scroll snapping: Users can flip through the images, viewing one image at a time by swiping or scrolling the page. So let’s see how this can be achieved with the new properties:

img {
  width: 200px;

.photoGallery {
  width: 200px;
  overflow: auto;
  white-space: nowrap;
  scroll-snap-points-x: repeat(100%);
  scroll-snap-type: mandatory;

The related HTML code looks like this:

<div class="photoGallery">
  <img src="img1.png"><img src="img2.png"><img src="img3.png">

Here’s a live demo:

See the Pen wKvYdK by Potch (@potch) on CodePen.

The code above creates a simple image gallery with three images, which can be scrolled through horizontally.

In this case the size of the images and their containing <div> are set to 200 pixels. The overflow: auto; displays a scrollbar on clients that support it. white-space: nowrap; serves to keep all images horizontally aligned. The definition “scroll-snap-points-x: repeat(100%);” sets a repeated horizontal snap point at 100% of the viewport width of the container <div>, in this case at 200 pixel intervals. Setting scroll-snap-type: mandatory; has the effect that snapping is forced. The viewport will always snap at a snap point, so the display will never stay in between two images.

Item lists

You’ve probably seen plenty of online product pages listing different features with an image of each feature and a description next to it, or an interface displaying a series of user testimonials.

In these cases, scroll snapping lets you align the sections so that maximal display space is used.

.features {
  width: 400px;
  height: 250px;
  padding: 0;
  overflow: auto;
  scroll-snap-type: proximity;
  scroll-snap-destination: 0 16px;

.features > section {
  clear: both;
  margin: 20px 0;
  scroll-snap-coordinate: 0 0;

img {
  width: 50px;
  height: 50px;
  margin: 5px 10px;
  float: left;

section:last-child {
  margin-bottom: 60px;

And here’s the related HTML code:

<div class="features">
  <section id="feature1">
    <img src="feature1.png"/>
    <p>Lorem ipsum...</p>
  <section id="feature2">
    <img src="feature2.png"/>
    <p>Lorem ipsum...</p>

Here’s a live demo:

See the Pen NGWOjN by Potch (@potch) on CodePen.

When you scroll within the example above, each feature section is positioned so that the top is aligned with the top of the viewport to display as much text as possible. This is achieved by applying scroll-snap-coordinate: 0 0; to the sections. The two zeros refer to the x and y coordinates of the element where it will snap to the container element. scroll-snap-destination: 0 16px; defines the offset position within the container element to which the inner elements should snap. In this case, that’s 16 pixels below the top of the container so that the text at top of the section has some margin at the top.

In addition to the properties currently defined within the CSS Scroll Snap Points specification, Gecko implements the additional properties scroll-snap-type-x and scroll-snap-type-y, for setting the snap type individually per axis. These long-hand properties may be added to the specification in the future.

Currently snap points can only be set through coordinates, either referring to the start edge of the container element or the ones within it. Sometimes this requires some calculation to set them at the right position. Future extensions to this feature may extend the functionality to be able to set snap points on the box model instead, which would make it easier to place them. There’s already a discussion about this within the www-style mailing list.

Has this new functionality caught your interest? Then it’s time to give it a try! And if you don’t remember how to use the different properties, you can always refer to the documentation on MDN.

View full post on Mozilla Hacks – the Web developer blog

Tagged on: , ,

One thought on “Scroll snapping explained

  1. J

    Thanx for this article. Looks promising.

    The last example does not work as expected when using a mouse. It does not snap to the second item in the list. Only when you press the scrollbar longer with the mouse. All other items snap correctly. With touch it works better, just touching the scrolllbar does the job. GREAT

Leave a Reply