16

I have written my own modal classes using css and have used it in my application successfully. However the issue i'm facing is when the overlay is open i can still scroll the background contents. How can i stop scrolling background contents when my modal/overlay is open?

This is my modal which opens on top of the overlay

<div>
  <div className="overlay"></div>
  {this.props.openModal ?
  <div>
    <div className="polaroid sixten allcmnt_bg_clr horiz_center2">
      {}
      <div className="mobile_header">
        <PostHeader/>
      </div>
      <div className="mobile_renderPost">
        { this.renderPostType() }
      </div>
      <div className="mobile_post_bottom"></div>
    </div>
  </div> : null}
</div>

my overlay css

.overlay {
  background-color: rgba(0, 0, 0, .70);
  position: fixed;
  width: 100%;
  height: 100%;
  opacity: 1;
  left: 0;
  right: 0;
  -webkit-transition: opacity .25s ease;
  z-index: 1001;
  margin: 0 auto;
}
Bhuwan
  • 16,080
  • 5
  • 30
  • 52
CraZyDroiD
  • 5,958
  • 28
  • 74
  • 160
  • 1
    Possible duplicate of [Prevent BODY from scrolling when a modal is opened](https://stackoverflow.com/questions/9538868/prevent-body-from-scrolling-when-a-modal-is-opened) – adeltahir Dec 21 '17 at 05:41

5 Answers5

27

One approach is hidden the overflow of the body element.

like this:

body.modal-open{
    overflow:hidden;
}

so in this case when you popup the modal you add a class to body and then when you close it you remove that class.

another approach is using a javascript to disable the scroll like this:

   document.documentElement.style.overflow = 'hidden';
   document.body.scroll = "no";

and then return it with

 document.documentElement.style.overflow = 'scroll';
 document.body.scroll = "yes";
M.R.Safari
  • 1,706
  • 3
  • 27
  • 42
5

When you open the modal, you can add overflow: hidden; to the body's style.

Or,

body.modal-opened {
   overflow: hidden;
}

And add modal-opened class to the body when opening and remove when you close the dialog.

adeltahir
  • 1,047
  • 2
  • 13
  • 29
3

Using JavaScript to add a class to the body with

overflow:hidden;

will work in most cases, but I beleive Safari on iPhone will still scroll slightly with jitter due to Touch Move and something like this will be needed.

function handleTouchMove(e)
{
  e.preventDefault();
}
function lockscreen()
{
  var body = document.getElementById("body");
  body.className += " lock-screen";
  body.addEventListener('touchmove', handleTouchMove, false);
}
function unlock()
{
  var body = document.getElementById("body");
 body.classList.remove("lock-screen");
 body.removeEventListener('touchmove', handleTouchMove);
}

to stop the user from still scrolling

Austin Jones
  • 649
  • 14
  • 28
  • 3
    It should be `document.body`. `document.getElementById("body")` won't work unless your `` element has `id="body"`. – Matt Browne Jun 07 '18 at 14:10
1

When the modal opens, hide the x/y scroll bars on the body.

.no-scroll {
    overflow: hidden;
}

Using JavaScript add the class to the body:

<body class="no-scroll">

</body>

Once you close the modal remove the class.

Get Off My Lawn
  • 30,739
  • 34
  • 150
  • 294
1

I had this problem too and tried every answer from setting the height on the body element to 100% or 100vh and overflow: hidden. This caused a few issues for me, starting with that using the hidden overflow with the 100vh made the page jump to the top whenever clicking the hamburger menu button.

The solution: adding the overflow:hidden property to the html tag. This worked perfectly where the menu would open, prevent the page from scrolling, and remain where the user is on the page without it jumping.

Since it looks like you're using React, here is an example of how I used it:

.lock-scroll {
  overflow: hidden;
}
const [open, setOpen] = useState(false)
useEffect(() => {
  const html = document.getElementsByTagName('html')[0]

  if (open) {
    html.classList.add('lock-scroll')
  } else {
    html.classList.remove('lock-scroll')
  }
  return (): void => {
    html.classList.remove('lock-scroll')
  }
}, [open])