Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dstorozhuk/b280d249d94bfe9a3dfce206cdd5342b to your computer and use it in GitHub Desktop.
Save dstorozhuk/b280d249d94bfe9a3dfce206cdd5342b to your computer and use it in GitHub Desktop.
Smooth Scroll behavior polyfill

The Scroll Behavior specification has been introduced as an extension of the Window interface to allow for the developer to opt in to native smooth scrolling. To date this has only been implemented in Chrome, Firefox and Opera.

There's a complete polyfill here (3.3KB minified). But most of the times, the following is enough for me (641 bytes minified):

smooth-scrolling-poyfill.js

Use as: scrollToElem('#elem-selector');

// native smooth scrolling for Chrome, Firefox & Opera
// @see: https://caniuse.com/#feat=css-scroll-behavior
const nativeSmoothScrollTo = elem => {
window.scroll({
behavior: 'smooth',
left: 0,
top: elem.getBoundingClientRect().top + window.pageYOffset
});
};
// polyfilled smooth scrolling for IE, Edge & Safari
const smoothScrollTo = (to, duration) => {
const element = document.scrollingElement || document.documentElement,
start = element.scrollTop,
change = to - start,
startDate = +new Date();
// t = current time
// b = start value
// c = change in value
// d = duration
const easeInOutQuad = (t, b, c, d) => {
t /= d/2;
if (t < 1) return c/2*t*t + b;
t--;
return -c/2 * (t*(t-2) - 1) + b;
};
const animateScroll = _ => {
const currentDate = +new Date();
const currentTime = currentDate - startDate;
element.scrollTop = parseInt(easeInOutQuad(currentTime, start, change, duration));
if(currentTime < duration) {
requestAnimationFrame(animateScroll);
}
else {
element.scrollTop = to;
}
};
animateScroll();
};
// detect support for the behavior property in ScrollOptions
const supportsNativeSmoothScroll = 'scrollBehavior' in document.documentElement.style;
// smooth scrolling stub
const scrollToElem = elemSelector => {
if (!elemSelector) {
return;
}
const elem = document.querySelector(elemSelector);
if (elem) {
if (supportsNativeSmoothScroll) {
nativeSmoothScrollTo(elem);
} else {
smoothScrollTo(elem.offsetTop, 600);
}
}
};
var nativeSmoothScrollTo=function(a){window.scroll({behavior:"smooth",left:0,top:a.getBoundingClientRect().top+window.pageYOffset})},smoothScrollTo=function(a,f){var c=document.scrollingElement||document.documentElement,d=c.scrollTop,g=a-d,k=+new Date,h=function(e){e=+new Date-k;var l=parseInt;var b=e/(f/2);1>b?b=g/2*b*b+d:(b--,b=-g/2*(b*(b-2)-1)+d);c.scrollTop=l(b);e<f?requestAnimationFrame(h):c.scrollTop=a};h()},supportsNativeSmoothScroll="scrollBehavior"in document.documentElement.style,
scrollToElem=function(a){a&&(a=document.querySelector(a))&&(supportsNativeSmoothScroll?nativeSmoothScrollTo(a):smoothScrollTo(a.offsetTop,600))};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment