Overscroll Behavior
Decides what a scroll box does with a scroll it has no room left to take: hand it to the box above, or keep it. Check out the MDN for how to use.
Scrolling a list that is already at its end used to stop there, whatever it was inside. It now carries on in the nearest scroll box above it, the way a page does on the web — and this property is how a box asks to keep a scroll to itself instead.
.page { width: 300px; height: 220px; padding: 12px; border-radius: 12px; background-color: #f1f5f9; } .list { height: 120px; flex-shrink: 0; padding: 8px; border-radius: 8px; background-color: white; overscroll-behavior: contain; } .row { padding: 6px; flex-shrink: 0; color: #475569; } .band { padding: 14px 6px; flex-shrink: 0; color: #64748b; } .tall { height: 140px; } .controls { flex-direction: row; gap: 8px; margin-bottom: 12px; } .controls .on { background-color: #6366f1; color: white; }
Values
auto(default) — a scroll this box cannot take goes on to the box above it.contain— it stops here. Any overscroll effect the box has of its own still plays.none— it stops here and there is no overscroll effect either.
Longhands
The shorthand takes one value for both axes or two, x first, as overflow does:
.list {
overscroll-behavior: none contain;
}
The axis a gesture runs along is the one that decides, so a contained y does not trap a sideways scroll:
overscroll-behavior-xandoverscroll-behavior-yoverscroll-behavior-inlineandoverscroll-behavior-block— the same two properties under their logical names. There are no vertical writing modes here, soinlineis always the horizontal axis andblockthe vertical one.
Notes
- Only a
<scroll>reads this. It has nothing to do on an element that does not scroll. - A gesture stays with whichever box took it: dragging a list down to its end and on past it does not then start dragging the page, which is the latching a browser does. A wheel is a separate event each time, so the next tick is handed on.
- Chaining walks the element tree rather than the transform hierarchy, so a
filteror aperspectivein between does not break it. - The difference between
containandnoneis the local overscroll effect, which here is<scroll>’selasticityprop — how far past its end the content can be pulled.nonetakes it away. Underautothe bounce is what a box does when there is nothing above to hand the scroll to, rather than something it absorbs the scroll into first. - The outermost scroll box has nothing above it, so a scroll it cannot take simply stops.