If you ever need to temporally disable scrolling on a specific scrollable element, then you will need to use JavaScript or CSS for it. Depending on your use case, you can choose between JavaScript and CSS solutions. Although in general terms the CSS solution is the most adopted one, JavaScript offers you a bit more of control and flexibility and allows you to decide how exactly you want to stop the scrolling.

1. Cancelling scroll using JavaScript

One of the options is to listen to the wheel event on the element you want to prevent the scrolling and then prevent the default behavior as well as stopping the propagation and returning a false value.

Something as simple as this, where #scrollable would be the ID of our scrollable element.

document.querySelector('#scrollable').addEventListener('wheel', preventScroll, {passive: false});

function preventScroll(e){
e.preventDefault();
e.stopPropagation();

return false;
}

Notice as well that we are using the option {passive: false} on the event listener. This is actually because we have to tell browsers that, eventually, we might call preventDefault and cancel the default behavior. This way the browser is aware of it and can decide how to treat the event. You can read more about it on the docs.

If you need to provide support for IE 11 you might need to add a fallback for the passive event param as it is not supported check if the passive event is supported.

Now, what if we want to enable or disable this dynamically? Here's an example with a couple of buttons, one to disable the scroll and another one to enable it:

See the Pen on CodePen.

If you want to apply it to multiple elements, it is as easy as iterating over them and applying them to the same function.

document.querySelector('.scrollable').forEach(function(item){
item.addEventListener('wheel', preventScroll);
});

Now, take a look at the CSS way because the JS way can get a bit more complicated if we take into account keyboard and touch scrolling.

2. Disabling scroll with only CSS

There's another way to disable scrolling that is commonly used when opening modals or scrollable floating elements. And it is simply by adding the CSS property overflow: hidden; on the element you want to prevent the scroll.

It is clearly the easiest solution if you want to disable scroll no matter what triggers it (mouse, keyboard, or touch), but at the same time, it won't give you the flexibility of choosing what to disable and what not.

There's a couple of differences with the previous way. They can be good for you, or not, depending on your use case:

  • It will also disable the keyboard scrolling too. So, you won't be able to move up or down by using the keyboard arrows and space bar, etc.

  • It will not allow you to scroll up/down by selecting text.

  • It will disable touch scroll too.

  • It might also prevent scrolling using "the third button" of the mouse, which is pressing the mousewheel while dragging the mouse. (If anyone can verify this for me that'd be great, as I don't have a mouse to test it at the moment :) )

So, how do we do it? We create a class that we will toggle whenever we need it and that all it does is preventing the scroll on the element we apply it.

.disable-scroll{
overflow-y: hidden;
}

Then, with JavaScript we simply add or remove it when we want:


function disable(){
document.querySelector('.scrollable').classList.add('disable-scroll');
}

function enable(){
document.querySelector('.scrollable').classList.remove('disable-scroll');
}

document.querySelector('#prevent').addEventListener('click', disable);
document.querySelector('#allow').addEventListener('click', enable);

Here's a working example:

See the Pen on CodePen.

3. Preventing keyboard scroll using JavaScript

If you decide to go for the JS solution, then you might also want to disable scroll through the keyboard.

In this case, we simply have to listen to the keydown event and prevent the default behavior when we detect they are pressing any key that can trigger a scroll movement, such as the keyboard arrows, spacebar, shift+space bar, pageup, pagedown etc.

Here's the code:

document.addEventListener('keydown', preventKeyBoardScroll, false);

function preventKeyBoardScroll(e) {
var keys = [32, 33, 34, 35, 37, 38, 39, 40];
if (keys.includes(e.keyCode)) {
e.preventDefault();
return false;
}
}

And here's the example:

See the Pen on CodePen.

4. Preventing touch scroll using JavaScript

And of course, we can't forget about the touch scroll. The CSS solution seems to make things like this much easier for us, but if we need total control over what we allow users to do and what not, then probably the JavaScript version is the way to go.

Regarding touch events, this is pretty similar to canceling the scroll for the wheel event.

We simply have to add the exact same function on a touchmove event listener:

var scrollable = document.querySelector('.scrollable');
scrollable.addEventListener('touchmove', disable, {passive: false});

See the Pen on CodePen.

5. Using a npm module to disable scroll

You will also find there are a few components and modules out there that give you this feature out of the box.

Some only apply to the whole document while others allow you to be applied to specific scrollable elements.

Here's a few I found: