on
Italy
- Get link
- X
- Other Apps
body.modal-open {
height: 100vh;
overflow-y: hidden;
}
That's good and all, but if we've scrolled through the <body>
element before opening the modal, we get a little horizontal reflow.
The width of the viewport is expanded about 15 pixels more, which is
exactly the with of the scroll bar. body {
height: 100vh;
overflow-y: hidden;
padding-right: 15px;
}
Note that the modal needs to be shorter than the height of the
viewport to make this work. Otherwise, the scroll bar on the body will
be necessary.body {
position: fixed;
}
Works now! The body will not respond when the screen is touched.
However, there's still a "small" problem here. Let's say the modal
trigger is lower down the page and we click to open it up. Great! But
now we're automatically scrolled back up to the top of the screen, which
is just as disorientating as the scrolling behavior we're trying to
resolve.stopPropagation is a little awkward with touch in iOS. But preventDefault
works well. That means we have to add event listeners in every DOM node
contained in the modal — not just on the backdrop or the modal box
layer. The good news is, many JavaScript libraries can do this,
including good ol' jQuery.If we know the top of the scroll location and add it to our CSS, then the body will not scroll back to the top of the screen, so problem solved. We can use JavaScript for this by calculating the scroll top, and add that value to the body styles:body { position: fixed; }
This works, but there's still a little leakage here after the modal is closed. Specifically, it appears that the page already loses its scroll position when the modal is open and the body set to be fixed. So we have to retrieve the location. Let's modify our JavaScript to account for that.document.body.style.position = 'fixed'; document.body.style.top = `-${window.scrollY}px`;document.body.style.position = ''; document.body.style.top = '';
const scrollY = document.body.style.top;
document.body.style.position = '';
document.body.style.top = '';
window.scrollTo(0, parseInt(scrollY || '0') * -1);
That does it! The body no longer scrolls when a modal is open and the
scroll location is maintained both when the modal is open and when it
is closed. Huzzah!
Comments
Post a Comment