CSS overscroll-behavior-block Property
This logical property controls how a scrollable element behaves when its scroll boundary is reached in the block direction. It determines if the scroll action is handed off to the parent container, a process known as scroll chaining.
| auto | The default behavior where scroll chaining occurs, allowing the parent container to scroll once the element boundary is reached. |
| contain | Prevents scroll chaining to the parent but maintains local overscroll effects like the rubber-band bounce on mobile. |
| none | Prevents both scroll chaining and local overscroll effects entirely. |
Code Examples
A basic example showing how to contain the scroll within a specific div to prevent the parent page from moving.
<div style="width: 300px; height: 200px; overflow: auto; overscroll-behavior-block: contain; border: 2px solid #333333;">
<p>Scroll down to the bottom of this box. Notice that the main page does not start scrolling once you reach the end of this content. The scroll baton is contained within this box.</p>
<div style="height: 500px; background: linear-gradient(#eeeeee, #cccccc);"></div>
</div>An advanced example using a modal container and JavaScript to dynamically toggle the scroll containment behavior.
<style>
.modal-content {
width: 80%;
height: 300px;
overflow-y: auto;
background-color: #ffffff;
overscroll-behavior-block: none;
}
</style>
<div id="myModal" class="modal-content">
<h3>Settings Menu</h3>
<p>Adjust your preferences below.</p>
<div style="height: 600px;">Long list of settings...</div>
<button onclick="disableScrollTrap()">Disable Trap</button>
</div>
<script>
function disableScrollTrap() {
const modal = document.getElementById("myModal");
// Use JS to dynamically allow the parent to scroll again
modal.style.overscrollBehaviorBlock = "auto";
modal.style.backgroundColor = "#e0ffe0";
}
</script>Pro Tip
If you are building a full-screen web app and want to stop the entire page from 'pulling down' and refreshing on mobile browsers, apply this property to the body or html tag. It is a much cleaner solution than trying to intercept and cancel touch events with JavaScript.
Deep Dive
Think of scroll chaining like a relay race. In the default "auto" state, when a user reaches the end of a scrollable box, the browser passes the "scroll baton" to the parent element, causing the whole page to start moving. The "overscroll-behavior-block" property acts as a finish line barrier. Setting it to "contain" or "none" stops that baton from being passed. Because this is a logical property, "block" refers to the direction text flows in a document. In a standard English layout, this is the vertical axis. If the writing mode changes to something like vertical-rl, the block direction becomes horizontal. This allows your layout logic to remain consistent across different languages and orientations.
Best Practices
Use "contain" on internal scrollable components like sidebars, chat windows, or dropdown menus. This prevents the frustrating user experience where scrolling to the bottom of a small list suddenly causes the entire background page to jump or move. Reserve "none" for cases where you want to completely eliminate the elastic bounce effect common on mobile operating systems, as it can make the interface feel more rigid.
Common Pitfalls
The most common mistake is trying to use this on an element that isn't actually scrollable. If "overflow" is not set to "auto" or "scroll", this property does nothing. Also, remember that "block" is not always "vertical." If you specifically want to target the Y-axis regardless of language settings, you should use "overscroll-behavior-y" instead.
Accessibility
Be careful when disabling scroll chaining. Users with motor impairments or those using specific input devices might rely on the natural flow of scroll hand-offs to navigate a page. Only trap the scroll if it serves a clear functional purpose, such as keeping a user focused within a modal or a complex map interface.
Dev Data Table: overscroll-behavior-block property
| default | auto |
| animatable | no |
| inherited | no |
| experimental | no |
| year_intro | 2019 |
| year_standard | 2021 |
| js_syntax_1 | element.style.overscrollBehaviorBlock = "contain"; |
| js_syntax_2 | element.style.setProperty("overscroll-behavior-block", "none"); |
| js_note | When using the style object, use camelCase. Ensure the element is actually scrollable via the overflow property for this to have any visible effect. |
| browsers | { "Chrome": 77, "Edge": 79, "Firefox": 73, "Safari": 16, "Opera": 64, "Chrome Android": 77, "Safari on iOS": 16, "Samsung Internet": 12, "Opera Mobile": 55 } |