How to emulate CSS Scroll Snap Points in Chrome?

Martin Vseticka picture Martin Vseticka · Jul 6, 2015 · Viewed 12.4k times · Source

Firefox 39, Safari 9 and IE11 provide support for CSS Scroll Snap Points. Chrome has the feature in development.

Is there a polyfill that would emulate the following CSS styles:

-webkit-scroll-snap-type: mandatory;
-ms-scroll-snap-type: mandatory;
scroll-snap-type: mandatory;
-webkit-scroll-behavior: smooth;
-ms-scroll-behavior: smooth;
scroll-behavior: smooth;
-webkit-scroll-snap-points-y: repeat(600px);
-ms-scroll-snap-points-y: snapInterval(0px, 600px); /* Old syntax */
scroll-snap-points-y: repeat(600px);
overflow-y: auto;
overflow-x: hidden;

until the feature is implemented by Chrome?

Answer

Luca Falasco picture Luca Falasco · Feb 8, 2018

If you're willing to consider a vanilla javascript re-implementation of this feature with a consistent cross browser behaviour you can use this library

Why

The main reason to use this instead of the native css solution is that it works in all modern browsers and has a customizable configuration to allow custom timing in transitions and scrolling detection.

How

The library re-implements the css snapping feature using vanilla javascript easing functions, and works using the values of the container element's scrollTop/scrollLeft properties and the scroll Event Listener

Example

import ScrollSnap from 'scroll-snap'

const snapConfig = {
  // snap-destination for x and y axes expressed as px|%|vw|vh
  snapDestinationX: '0%',
  snapDestinationY: '90%',
  // time in ms after which scrolling is considered finished
  timeout: 100,
  // duration in ms for the smooth snap
  duration: 300,
  // threshold to reach before scrolling to next/prev element, expressed in the range [0, 1]
  threshold: 0.2,
  // custom easing function
  easing: easeInOutQuad,
}

function callback () {
  console.log('called when snap animation ends')
}

const element = document.getElementById('container')
const snapObject = new ScrollSnap(element, snapConfig)

snapObject.bind(callback)

// unbind the element
// snapObject.unbind();