CSS overscroll-behavior: Stop Scroll Chaining
Scroll chaining occurs when a user scrolls to the boundary of a
nested element and the browser automatically passes the scrolling action
to the parent page, often causing disorienting layout shifts. The CSS
overscroll-behavior property solves this issue by giving
developers control over how a scroll container interacts with its parent
boundary. By setting this property, you can contain scroll interactions
within specific components—such as modal windows, chat sidebars, and
dropdown menus—eliminating the need for complex, performance-heavy
JavaScript workarounds.
Understanding Scroll Chaining
By default, web browsers link scrollable containers together in a chain. When a user reaches the top or bottom of a scrollable nested container (like an inner list or modal dialog) and continues scrolling, the browser transfers that momentum to the outer page body. On mobile devices, this behavior often triggers unwanted browser features, such as pull-to-refresh, navigation swipes, or elastic bounce effects on the entire page, degrading the overall user experience.
The Role of
overscroll-behavior
The overscroll-behavior property determines what a
browser does when reaching the boundary of a scrolling area. It allows
developers to sever the connection between nested containers and the
viewport scroll.
The property accepts three primary values:
auto: The default setting. Scroll momentum propagates to the parent container once the inner boundary is reached, allowing standard scroll chaining and pull-to-refresh triggers.contain: Prevents scroll chaining. When the boundary of the element is reached, scrolling stops and does not propagate to the parent container. However, native overscroll effects local to the element (such as an elastic bounce on iOS) are preserved within the container itself.none: Completely disables both scroll chaining and local boundary affordances. Scrolling does not transfer to the parent, and default browser behaviors like rubber-banding or pull-to-refresh are entirely suppressed for that element.
Practical Applications
1. Modal Dialogs and Overlays
A common issue in web applications is the background page scrolling
while a user reads through a modal overlay. Applying
overscroll-behavior: contain; directly to the modal content
container prevents the background document from scrolling when the modal
reaches its top or bottom limit.
.modal-content {
overflow-y: auto;
overscroll-behavior: contain;
}2. Fixed Sidebars and Drawers
For navigation panels, sidebars, or fixed chat widgets that sit
alongside main content, applying
overscroll-behavior: contain; ensures that scrolling
through long menus will never accidentally scroll the main page
underneath.
3. Preventing Mobile Pull-to-Refresh
When building custom pull-to-refresh interactions or Progressive Web
Apps (PWAs), native mobile pull-to-refresh can interfere with the
interface. Setting overscroll-behavior-y: none; on the root
<html> or <body> element disables
the browser's default refresh action without breaking standard page
scrolling.
body {
overscroll-behavior-y: none;
}Directional Control
The property can also be split along specific axes for granular control:
overscroll-behavior-x: Controls horizontal boundary chaining, useful for horizontal carousels and swipeable cards without interfering with vertical navigation.overscroll-behavior-y: Controls vertical boundary chaining, ideal for vertical lists, modals, and disabling pull-to-refresh.
Advantages Over JavaScript Solutions
Historically, developers prevented scroll chaining by attaching
touchmove or wheel event listeners with
e.preventDefault(), or by toggling
overflow: hidden on the <body> element.
These techniques introduce significant drawbacks:
- Performance Overhead: Passive event listeners must be bypassed, forcing the browser to wait for JavaScript execution before rendering frame updates, which causes scroll stutter.
- Layout Shifts: Dynamically toggling
overflow: hiddenon the body often causes layout jumps due to scrollbars appearing and disappearing. - Accessibility Issues: Script-based scroll locks can trap keyboard users or disrupt assistive technology navigation.
By delegating boundary management directly to the browser's
compositor layer through CSS, overscroll-behavior ensures
smooth, native 60fps scrolling performance, eliminates JavaScript
dependencies, and provides a predictable user interface.