How to prevent the page from scrolling on mobile is often a recurring issue. We usually want to stop page scrolling on mobile when a menu is open or a lightbox overlay is there. I only discovered the fix recently, using a JavaScript library named “Body scroll lock”.
How to prevent the page from scrolling on mobile, enable and disable page scroll with JavaScript
I had the issue so many times to deactivate scroll using a “noscroll” class on the body tag, but this doesn’t work for mobile scroll (and touch move)
.noscroll {
overflow: hidden;
}
Moreover, we often want to keep the scroll active in the overlayed element, for instance, allow with a long menu to scroll on a smaller viewport.
Here is the solution with Body scroll lock, a JavaScript library
Enables body scroll locking (for iOS Mobile and Tablet, Android, desktop Safari/Chrome/Firefox) without breaking scrolling of a target element (eg. modal/lightbox/flyouts/nav-menus).
https://www.npmjs.com/package/body-scroll-lock
And you can use a data attribute body-scroll-lock-ignore to keep the scroll for your menu/modal content/etc.
import * as bodyScrollLock from '../utils/body-scroll-lock';
export const lockScroll = (el) => {
if (el) {
bodyScrollLock.disableBodyScroll(el, {
allowTouchMove: (target) => {
while (target && target !== document.body) {
if (target.hasAttribute('body-scroll-lock-ignore')) {
return true;
}
target = target.parentElement;
}
return false;
},
});
}
};
export const unlockScroll = (el) => {
if (el) {
bodyScrollLock.enableBodyScroll(el);
}
};
export const clearScrollLocks = () => {
if (bodyScrollLock.clearAllBodyScrollLocks) {
bodyScrollLock.clearAllBodyScrollLocks();
}
};
And then something like
import { lockScroll, unlockScroll } from '../components/body-scroll-lock-wrapper';
[...]
if (mobileMenuOpen && window.innerWidth <= 600) {
lockScroll(navElement);
} else {
unlockScroll(navElement);
}
That’s it, read more about it at https://github.com/willmcpo/body-scroll-lock
Hope this solves your scroll issues and helps you!