CSS overscroll-behavior-inline Property
This property controls how a browser handles scroll overflow in the inline direction when the boundary of a scrollable area is reached.
| auto | Allows the default scroll chain behavior where the parent container scrolls after the element reach its boundary. |
| contain | Prevents scroll chaining to the parent but preserves local overscroll effects like the rubber-band bounce on mobile. |
| none | Prevents scroll chaining and also disables any local overscroll cues or bounce effects. |
Code Examples
A basic horizontal scroll area that uses contain to prevent the parent page from scrolling when the boundary is reached.
<div style="width: 300px; height: 100px; overflow-x: auto; overscroll-behavior-inline: contain; background: #f0f0f0; border: 2px solid #333333;">
<div style="width: 600px; padding: 20px;">
Scroll me horizontally. When you hit the end, the main page won't move.
</div>
</div>An advanced example showing a horizontal list where the overscroll behavior is toggled dynamically using JavaScript.
<div id="advancedContainer" style="width: 100%; overflow-x: scroll; overscroll-behavior-inline: auto; white-space: nowrap; padding: 10px; background: #eeeeee;">
<div style="display: inline-block; width: 200px; height: 100px; background: #ff0000; margin-right: 10px;">Item 1</div>
<div style="display: inline-block; width: 200px; height: 100px; background: #00ff00; margin-right: 10px;">Item 2</div>
<div style="display: inline-block; width: 200px; height: 100px; background: #0000ff; margin-right: 10px;">Item 3</div>
</div>
<button onclick="toggleLock()">Toggle Scroll Lock</button>
<script>
function toggleLock() {
const el = document.getElementById("advancedContainer");
const current = el.style.overscrollBehaviorInline;
el.style.overscrollBehaviorInline = (current === "contain") ? "auto" : "contain";
console.log("Overscroll behavior set to: " + el.style.overscrollBehaviorInline);
}
</script>Pro Tip
You can pair this with scroll-snap-type to create high-end mobile carousels that feel like native apps. It ensures the horizontal swipe stays within the widget without the page wobbling or shifting vertically while the user is interacting with your content.
Deep Dive
Think of scroll chaining like a relay race. By default, when you finish scrolling a small box, the browser passes the scroll baton to the parent page, making the whole page move. This property lets you drop the baton so the parent stays still. Because it is a logical property, it targets the inline axis, which is horizontal in standard left-to-right languages. If you change the writing-mode to a vertical style, the inline axis shifts to vertical automatically. This makes your layout more robust for international audiences compared to using the physical overscroll-behavior-x property.
Best Practices
Use contain when you have horizontal components like image carousels or side-scrolling navigation bars inside a vertical page. This keeps the user focused on the component and prevents the frustrating experience of the entire page shifting when they reach the end of your gallery. Stick to auto for most scenarios to maintain the natural flow of the web unless you have a specific UI reason to block it.
Common Pitfalls
A common mistake is confusing inline with block. In a standard website, inline is horizontal and block is vertical. If you are trying to stop a sidebar from scrolling the main page, you likely want overscroll-behavior-block or the shorthand overscroll-behavior. Also, remember that none kills the bounce effect on mobile devices, which can make the UI feel unresponsive or broken to touch users.
Accessibility
Be careful not to trap your users. If you disable scroll chaining on an element that covers a large portion of the screen, a user might find it difficult to continue scrolling down the page. Always ensure there is enough clickable or scrollable area outside the element so users can escape the contained scroll zone.
Dev Data Table: overscroll-behavior-inline property
| default | auto |
| animatable | no |
| inherited | no |
| experimental | no |
| year_intro | 2017 |
| year_standard | 2022 |
| js_syntax_1 | element.style.overscrollBehaviorInline = 'contain'; |
| js_syntax_2 | element.style.setProperty('overscroll-behavior-inline', 'contain'); |
| js_note | When manipulating this property through JavaScript, use camelCase for the style object property name or the kebab-case string within the setProperty method. |
| browsers | { "Chrome": 77, "Edge": 77, "Firefox": 73, "Safari": 16, "Opera": 64, "Chrome Android": 77, "Safari on iOS": 16, "Samsung Internet": 12, "Opera Mobile": 57 } |