Prevent Body Scrolling

By  on  

One of my pet peeves with fixed or absolute positioned elements is the <body> scrolling while you scroll the the positioned element.  Have you ever tried scrolling a dialog and seeing the page scroll in the background?  Awful user experience, bordering on embarrassing.  Yikes.

So what's the best way to prevent the <body> scrolling in the background?  Pass on scroll events and preventDefault or stopPropagation, that wont work.  The easiest way is a simple CSS snippet:

body.noScroll { /* ...or body.dialogShowing */
  overflow: hidden;
}

Preventing overflow on the entire <body> assures scrolling on elements other than the desired fixed or absolute element wont happen.  It's an easy way to freeze the page for a hovered focus element.

This trick has been used forever -- make sure you keep it in your toolbox!

Recent Features

  • By
    Facebook Open Graph META Tags

    It's no secret that Facebook has become a major traffic driver for all types of websites.  Nowadays even large corporations steer consumers toward their Facebook pages instead of the corporate websites directly.  And of course there are Facebook "Like" and "Recommend" widgets on every website.  One...

  • By
    5 Ways that CSS and JavaScript Interact That You May Not Know About

    CSS and JavaScript:  the lines seemingly get blurred by each browser release.  They have always done a very different job but in the end they are both front-end technologies so they need do need to work closely.  We have our .js files and our .css, but...

Incredible Demos

  • By
    Unicode CSS Classes

    CSS class name structure and consistency is really important; some developers camelcase classnames, others use dashes, and others use underscores.  One thing I've learned when toying around by HTML and CSS class names is that you can actually use unicode symbols and icons as classnames.

  • By
    Image Manipulation with PHP and the GD Library

    Yeah, I'm a Photoshop wizard. I rock the selection tool. I crop like a farmer. I dominate the bucket tool. Hell, I even went as far as wielding the wizard wand selection tool once. ...OK I'm rubbish when it comes to Photoshop.

Discussion

  1. MaxArt

    Keep in mind that overflow: hidden also hides the scrollbar. Usually not a problem on mobile, but on desktop it creates an annoying effect because it resizes the viewport.

    • David

      Except when you are on Mac, there the scrollbar lays above the page content and simple fades in and out without actually affecting the available width. Long live consistency…

    • Shawn D

      True, unless you have ‘Always Show Scrollbars’ turned on in general prefs or are using an external mouse

  2. Daniel

    Bootstrap uses this technique in theirs modals, but this is not very well supported on mobile devices:
    http://v4-alpha.getbootstrap.com/getting-started/browsers-devices/#modals-navbars-and-virtual-keyboards

  3. Onairda

    How would you make the body fixed and the modal window scrollable in case its content exceeds the window size?

    Applying the overflow: hidden on body will prevent the whole page to scroll.

  4. Add overflow: hidden; property on body tag and set position fixed of inner element.

  5. Guest

    In 80% of cases, modal or whatever, will be called when window is somewhat scrolled from top of the page.

    overflow: hidden;

    on body will instantly fix window on top of the page, and again, you’ll have nasty effect.

    • Anna

      This is the problem I’m encountering, and have had no luck in finding a solution! :(

  6. Adam

    In some cases (eg. React), you don’t want to change ‘external world’ state.

    Is there any way to prevent body from scrolling from the level of some element that is supposed to stop body scrolling without touching body element??

  7. Luca

    Awesome

  8. leny

    also in safari(mobile) the body keeps scrolling.

  9. @Adam, you can use something like https://github.com/iest/react-body-classname with React (it’s fine to change ‘external world’ state when needed).

    • lulz

      yes, just add another dependency to your project o.O

  10. Oliver

    This works for desktop but not for mobile. Is there a solution?

  11. willmcpo

    Check out https://www.npmjs.com/package/body-scroll-lock.

    Locks body scroll without locking scroll of a target element (eg. Modal) for iOS and other devices, as well as desktop browsers.

    Yes works for iOS.

    Here’s a demo: http://wp-os.s3-website-ap-southeast-2.amazonaws.com/body-scroll-lock-demo/index.html.

    You can read more about the rationale of the package at https://medium.com/jsdownunder/locking-body-scroll-for-all-devices-22def9615177.

  12. Some primate

    You should encounter another issue, the body scroll state is lost and page scrolls to top.

  13. Charles Robertson

    This does not work on iOS12. Add position:fixed as well for iOS12….

  14. James Filby

    As others have pointed out, this currently only appears to have very limited mobile support, specifically Chrome and Edge browser seem to support this behaviour, all others continue to allow the user to scroll the body.

  15. Rob

    Can anyone offer me a userscript for greasemonkey to use
    in palemoon (firefox “legacy”) that would prevent the sidebar
    history from scrolling to top each time i open portions of urls
    visited a day or more before..

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!