268

I would like to disable scrolling on the HTML body completely. I have tried the following options:

  • overflow: hidden; (not working, did not disable scrolling, it just hid the scrollbar)

  • position: fixed; (this worked, but it scrolled completely to the top, which is unacceptable for this specific application)

I was unable to find any alternatives to these two options, are there any more?

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137

12 Answers12

430

Set height and overflow:

html, body {margin: 0; height: 100%; overflow: hidden}

http://jsfiddle.net/q99hvawt/

pavel
  • 26,538
  • 10
  • 45
  • 61
  • 5
    forgot about "html, " before "body. –  Feb 09 '15 at 14:21
  • 6
    Not working on iOS when you have a overlay element that has fixed position. – notQ Nov 09 '18 at 09:00
  • 2
    You could just add the "overflow":"hidden" and it will work fine. – JPG Sep 20 '19 at 15:29
  • 1
    This solution did not immediately work for me, but after inspection "margin" was being overridden somewhere. Setting that element's "margin: 0;" did the trick. – joaoprib Jun 20 '20 at 23:58
  • 3
    Sometimes you would prefer using `height: 100vh` ; ) – neox5 Feb 08 '21 at 19:56
  • @neox5 Unfortunately, Safari is the new IE. And on iOS, every browser is just a wrapper for Safari. In Chrome on iOS, `100vh` includes the viewport and the browser chrome. Setting a height of `100vh` will actually make it too tall. – Swivel Aug 22 '22 at 15:30
  • 1
    @neox5 You might want to look into `100dvh` or one of the other newer variants -- More info on the bug here: https://nicolas-hoizey.com/articles/2015/02/18/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers/ – Swivel Aug 22 '22 at 15:34
23

To accomplish this, add 2 CSS properties on the <body> element.

body {
   height: 100%;
   overflow-y: hidden;
}

These days there are many news websites which require users to create an account. Typically they will give full access to the page for about a second, and then they show a pop-up, and stop users from scrolling down.

The Telegraph

EDIT

In addition, some websites (e.g. Quora) also make portions of text blurry. In general they do this by applying the following CSS.

filter: blur(3px);
bvdb
  • 22,839
  • 10
  • 110
  • 123
  • this hides the scrollbar. However, the question is specifically asking for an alternative to hiding the scrollbar – DataGeek Apr 10 '20 at 03:38
  • 2
    @DataGeek , this does not only hide the scrollbar, it also stops the ability to scroll down. And as I understand that is what was asked for. i.e. not just hiding it, but also making it impossible to scroll down. – bvdb Apr 10 '20 at 20:00
22

HTML css works fine if body tag does nothing you can write as well

<body scroll="no" style="overflow: hidden">

In this case overriding should be on the body tag, it is easier to control but sometimes gives headaches.

IKavanagh
  • 6,089
  • 11
  • 42
  • 47
Lalo
  • 323
  • 3
  • 2
  • 41
    This is not valid HTML5 – mbomb007 Jan 30 '18 at 20:28
  • 1
    @mbomb007 Can you please comment on the mistake here related to HTML5? – Ethan Feb 21 '19 at 12:53
  • 19
    @Ethan The `scroll` attribute is not valid on the `` tag. It's not listed as valid on any spec I can find. [w3schools](https://www.w3schools.com/tags/tag_body.asp); [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body); [Quackit](https://www.quackit.com/html_5/tags/html_body_tag.cfm) – mbomb007 Feb 21 '19 at 15:58
18

This post was helpful, but just wanted to share a slight alternative that may help others:

Setting max-height instead of height also does the trick. In my case, I'm disabling scrolling based on a class toggle. Setting .someContainer {height: 100%; overflow: hidden;} when the container's height is smaller than that of the viewport would stretch the container, which wouldn't be what you'd want. Setting max-height accounts for this, but if the container's height is greater than the viewport's when the content changes, still disables scrolling.

joebjoe
  • 247
  • 2
  • 10
  • this saved my day for desktop browsers without unwanted side effect of scroll-top-top. but didn't work on mobile browsers (iphone5s and android). – bob Jul 08 '20 at 02:34
10
  • Using React >= 17.8?
  • Want to do this conditionally?

useEffect to the rescue!

function useImperativeDisableScroll({ element, disabled }) {
    useEffect(() => {
        if (!element) {
            return
        }

        element.style.overflowY = disabled ? 'hidden' : 'scroll'

        return () => {
            element.style.overflowY = 'scroll'
        }
    }, [disabled])
}

You could use this with e.g.

useImperativeDisableScroll({ element: document.body, disabled: true })

Depending on your use case, you may have better luck with

useImperativeDisableScroll({
    element: document.scrollingElement,
    disabled: true
})

Note however that at time of writing, you might have to polyfill document.scrollingElement.

Useful links:

8

There is another convenient way to disable scrolling without dynamically changing the body element when you need to create a popup component for your web app. First, add this style:

body:has(.requires-no-scroll) {
  overflow: hidden;
}

Then, when you create/open any popup, just add this class to it, and its presence will block the scrolling automatically (and unblock it as you remove the popup):

<div class="popup requires-no-scroll">
  ...
</div>

This is good for reactive apps when you show the popup based on some reactive boolean variable: the scrolling blocks by itself and you don't need to do anything else.

David
  • 161
  • 2
  • 6
  • I like this elegant solution (disregarding the probably costly selector). It worked when I failed with an [`overscroll-behavior`](https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior) solution. `:has` still won’t work in Firefox, but okay. – dakab Aug 31 '23 at 06:05
4

Why don't you try this:

<style type="text/css">
html, body {
  overflow: hidden;
}
</style>
Maizied Hasan Majumder
  • 1,197
  • 1
  • 12
  • 25
4

This would prevent page scroll:

body, html {
  overflow: hidden
}
Sharhabeel Hamdan
  • 1,273
  • 13
  • 15
2

If you're ok with the page scrolling to the top. you can do:

position: fixed;

on the element you don't want to be scrollable. I know it's not the answer you wanted but I'm answering the title directly for those who Googled for this issue.

Embedded_Mugs
  • 2,132
  • 3
  • 21
  • 33
1

HTML

<body id="appBody">
....
</body>

JS

function disableBodyScroll(){
 const element = document.querySelector("#appBody");
 element.classList.add("stop-scroll");
}

function enableBodyScroll(){
 const element = document.querySelector("#appBody");
 element.classList.remove("stop-scroll");
}

CSS

 .stop-scroll {
      margin: 0;
      height: 100%;
      overflow: hidden;
    }
Anup Bangale
  • 581
  • 7
  • 7
  • bbc seems to use some combo of above can be made viewable by setting something like height: 200vh; max-height: 200vh; overflow: auto; on the main element. It's not obvious how they actually prevent the scroll. e.g. https://www.bbc.co.uk/news/uk-england-tyne-58925807 – Daniel Oct 16 '21 at 00:55
  • Can also be circumvented by disabling javascript – Daniel Oct 20 '21 at 23:08
1

If you want to disable scrolling on the main child of your body but not the body itself (out of necessity/other reasons) you could apply such a class to it.

.app {
   height: 100vh;
   overflow-y: hidden;
   filter: blur(npx);
}
Ali Bakhshandeh
  • 433
  • 6
  • 10
0

For anyone struggling as much as i am. If your root element is Html then add overflow: hidden to it instead of body