Before this new CSS I’m about to introduce existed, locking an element into the viewport on scroll required rigging up some JavaScript. As you may know, JavaScript has a well-earned reputation to be tricky when paired with scrolling behavior.

The new CSS Scroll Snap Points spec promises to help, allowing for this kind of behavior using very few lines of CSS.

As happens with very new web tech, this spec has changed over time. There is “old” and “new” properties and values. It’s promising though, as supporthas shot up quickly. I’ll teach you how to get the widest support in this in-between stage.

Polyfilled Demo

The demo below has horizontal scrolling. It’s responsive: each “panel” is the width and height of the viewport (thanks to vh and vw units).

It uses a polyfill, but in order to use it (and support is still low enough that I suggest you do), you have to support the “old” values, which is why I’ll cover them, too.

See the Pen Simple Responsive Scroll Snap Point Demo by Sarah Drasner (@sdras) on CodePen.

  • If you’re looking in Firefox: it has the best current support, so you can mostly clearly see how the native behavior looks and feels.
  • If you’re looking Chrome or Opera: don’t have any support, so any behavior you notice in those browsers can be attributed to the polyfill entirely.
  • If you’re looking in Edge or IE: it probably won’t work at all. These browsers have partial support, but apparently not enough to make this work.
  • If you’re looking on a mobile device: iOS 9 supports it (tested on an iPhone 6), but I’ve seen the easing behavior act pretty weird. No Chrome/Android support, but the polyfill kicks in and handles it pretty well (tested on a Android Nexus 6).

Note I’m using Autoprefixer in the Pen to automatically give me all the necessary vendor prefixed properties.

Here’s the code used to make the magic:

.scroller { scroll-snap-type: mandatory; /* older spec implementation */ scroll-snap-destination: 0% 100%; scroll-snap-points-x: repeat(100%);
}

Pretty slim! Let’s break down these properties one by one.

Current CSS Scroll Snap Properties

scroll-snap-type

scroll-snap-type: none | mandatory | proximity; 

A mandatory value is what you might think it would mean: that the element must come to rest on a snap point even when there are no active scrolling actions taken. If content is somehow modified or updated, the page finds the snap point again.

The proximity value is close to mandatory, but less strict. If the browser changes in size or content is added, it may or may not find the snap point again, depending on how close to a snap point it is.

From what I

Before this new CSS I’m about to introduce existed, locking an element into the viewport on scroll required rigging up some JavaScript. As you may know, JavaScript has a well-earned reputation to be tricky when paired with scrolling behavior.

The new CSS Scroll Snap Points spec promises to help, allowing for this kind of behavior using very few lines of CSS.

As happens with very new web tech, this spec has changed over time. There is “old” and “new” properties and values. It’s promising though, as supporthas shot up quickly. I’ll teach you how to get the widest support in this in-between stage.

Polyfilled Demo

The demo below has horizontal scrolling. It’s responsive: each “panel” is the width and height of the viewport (thanks to vh and vw units).

It uses a polyfill, but in order to use it (and support is still low enough that I suggest you do), you have to support the “old” values, which is why I’ll cover them, too.

See the Pen Simple Responsive Scroll Snap Point Demo by Sarah Drasner (@sdras) on CodePen.

  • If you’re looking in Firefox: it has the best current support, so you can mostly clearly see how the native behavior looks and feels.
  • If you’re looking Chrome or Opera: don’t have any support, so any behavior you notice in those browsers can be attributed to the polyfill entirely.
  • If you’re looking in Edge or IE: it probably won’t work at all. These browsers have partial support, but apparently not enough to make this work.
  • If you’re looking on a mobile device: iOS 9 supports it (tested on an iPhone 6), but I’ve seen the easing behavior act pretty weird. No Chrome/Android support, but the polyfill kicks in and handles it pretty well (tested on a Android Nexus 6).

Note I’m using Autoprefixer in the Pen to automatically give me all the necessary vendor prefixed properties.

Here’s the code used to make the magic:

.scroller { scroll-snap-type: mandatory; /* older spec implementation */ scroll-snap-destination: 0% 100%; scroll-snap-points-x: repeat(100%);
}

Pretty slim! Let’s break down these properties one by one.

Current CSS Scroll Snap Properties

scroll-snap-type

scroll-snap-type: none | mandatory | proximity; 

A mandatory value is what you might think it would mean: that the element must come to rest on a snap point even when there are no active scrolling actions taken. If content is somehow modified or updated, the page finds the snap point again.

The proximity value is close to mandatory, but less strict. If the browser changes in size or content is added, it may or may not find the snap point again, depending on how close to a snap point it is.

From what I