How to stop a modal from scrolling the page behind it
Are you a freelancer struggling to secure your first few clients?
Landing clients is the hardest part of freelancing. Client Bytes has 37 tactics from two 7-figure agency owners to help.
You open a modal or a sidebar with its own scrollable content. You scroll to the bottom of it. The page behind it starts scrolling too. This is called scroll chaining, and it is one of those bugs that makes a site feel unfinished. CSS overscroll-behavior fixes it with one line. No JavaScript scroll event listeners, no body overflow: hidden hacks.
The fix
.modal-content {
overflow-y: auto;
overscroll-behavior: contain;
}
overscroll-behavior: contain tells the browser to keep scroll inside this element. When the user hits the top or bottom of the modal, scroll stops there. It does not bleed through to the page below. That is the entire fix.
Where this comes up constantly
/* modal with scrollable content */
.modal {
overflow-y: auto;
max-height: 80vh;
overscroll-behavior: contain;
}
/* sidebar navigation */
.sidebar {
overflow-y: auto;
height: 100vh;
overscroll-behavior: contain;
}
/* chat message list */
.message-list {
overflow-y: auto;
flex: 1;
overscroll-behavior: contain;
}
Any scrollable container that lives on top of another scrollable area is a candidate for this property. Modals, drawers, sidebars, dropdown menus, chat windows, comment threads inside a page.
The three values
/* default - scroll chains to parent when hitting the edge */
overscroll-behavior: auto;
/* stops chaining and pull-to-refresh, keeps local bounce/glow */
overscroll-behavior: contain;
/* stops everything including mobile bounce effect */
overscroll-behavior: none;
contain is the right choice for almost every case. none is occasionally useful on full-screen app-like interfaces where you want to suppress the iOS rubber-band effect entirely.
Also fixes pull-to-refresh accidentally triggering inside a modal. On mobile Chrome, pulling down inside a scrollable modal can trigger the browser’s pull-to-refresh reload. overscroll-behavior: contain stops that too, without disabling pull-to-refresh on the page itself.
Why it matters
- Instant fix, one line. A bug that made your modal or sidebar feel broken is fixed in the time it takes to type one property.
- No body overflow hack. The old workaround was toggling overflow: hidden on the body when a modal opens, which causes layout shift as the scrollbar disappears. This property avoids that entirely.
- All browsers. Widely supported. Available in Chrome, Firefox, and Edge since 2022. Safari on iOS does not support it, so test on mobile before shipping.
Search your codebase for any element with overflow-y: auto or overflow-y: scroll that sits on top of the page. Every one of them is a candidate for overscroll-behavior: contain.
Happy coding!
Marko