Skip to content

Prevent history navigation on horizontally-scrolling elements with CSS

Behold a horizontally-scrolling element:

.reel {
display: flex;
overflow-x: scroll;
}

This pattern is particularly useful on mobile devices as an alternative to stacking for breaking a grid apart, but its utility is not limited to small screens. A horizontally-scrolling section can also become the basis of an image slideshow on desktop browsers.

When people use the trackpad for navigating horizontally (often, with a two-finger gesture), we get an unintended side-effect: the gesture coincides with navigating through the browser history. A two-finger swipe to the right triggers the browser Back action, while two fingers to the left triggers the Forward action. When you reach the edges as you scroll the container, you often accidentally navigate away from the page (there's probably a name for the phenomenon).

To prevent the navigation, we can use the overscroll-behavior CSS property. A value of none or contain will make sure the excess scroll does not ripple to the container's ancestors and, ultimately, the page:

.reel {
display: flex;
overflow-x: scroll;
overscroll-behavior-x: contain;
}

Here's a demo highlighting the difference.

At the time of writing, this property is supported in Firefox 1, Chrome 2, and Edge, so most desktop users will benefit from the enhanced behavior.

For extra credit also opt into smooth, accelerated scrolling in mobile Safari with -webkit-overflow-scrolling: touch. While iOS / iPadOS 13 makes this the default, it's still a nice, ahem, touch for older versions.

Updates

March 26, 2022: The overscroll-behavior CSS property is now available for testing in Safari Technology Preview 142 (yay!)

August 7, 2022: But history navigation is explicitly allowed despite overscroll-behavior (sad tromobone) [WebKit#240183].


1 There's a small issue in Firefox with the first swipe.

2 I stumbled upon a peculiar combination that made Chrome ignore the declaration.