
Controlling Scroll Chaining with CSS overscroll-behavior
A notorious user experience annoyance on the web is scroll chaining: when a user scrolls to the bottom of a nested modal dialog, sidebar navigation, or dropdown menu, the browser automatically transfers the scroll gesture to the underlying body document. This causes disorienting page jumps and unexpected navigation shifts.
Traditionally, developers intercepted mouse wheel and touch events with JavaScript to toggle overflow: hidden on the <body>. The CSS overscroll-behavior property solves this natively with zero JavaScript.
Example
Consider an off-canvas navigation drawer that contains more items than fit in the viewport:
<aside class="sidebar-drawer" aria-label="Navigation drawer">
<ul class="nav-links">
<li><a href="/dashboard">Dashboard</a></li>
<li><a href="/settings">Settings</a></li>
<!-- Many more scrollable items -->
</ul>
</aside>
Implementation
Applying overscroll-behavior: contain tells the browser to isolate the scroll boundary to that element:
.sidebar-drawer {
position: fixed;
top: 0;
left: 0;
width: 320px;
height: 100vh;
overflow-y: auto;
overscroll-behavior: contain;
background: #ffffff;
border-right: 1px solid var(--lightgray);
}
By setting contain, once the user reaches the end of .sidebar-drawer, scrolling ceases rather than bubbling to the main document.
Main Point: overscroll-behavior: contain eliminates unwanted scroll chaining and pull-to-refresh triggers natively without JavaScript touch-event listeners.
Credits
Photo by Sean Oulashin on Unsplash