Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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))};
@winng51
Copy link

winng51 commented Oct 29, 2021

it works, thx!

@technik300
Copy link

arrow function expression in IE11:
const nativeSmoothScrollTo = elem => {
... and other
replaced by:
const nativeSmoothScrollTo = function(elem) {
and it works.
TNX!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment