overscroll-behavior

Avatar of Mojtaba Seyedi
Mojtaba Seyedi on (Updated on )

The overscroll-behavior CSS property controls whether an element will use “scroll chaining” or not. You have likely experienced this behavior before and perhaps took it for granted that scrolling works like this on the web! If you are inside of an element that has its own scrolling (say it’s vertical) and you have scrolled down to the bottom of it, then by default, the next parent element up (maybe the page itself) starts to scroll in that direction. If you don’t want that default, overscroll-behavior is what controls it.

In other words, it specifies how the browser behaves when reaching the boundary of a scrolling area.

.stop-scroll-chaining {
  overscroll-behavior: contain; /* or "none" */
}

overscroll-behavior is a shorthand for overscroll-behavior-x and overscroll-behavior-y and it is defined in the CSS Overscroll Behavior Module Level 1 Specification which is currently in Editor’s Draft status.

Scroll chaining and overscroll affordances

Scroll chaining is when scrolling is propagated from one scroll container to an ancestor scroll container. You can see this effect in following video:

As you can see, once the list box’s scroll boundary is reached, the container behind it starts to scroll and then the underlying page follows the scroll chain as well.

Overscroll affordance is stuff like the overscroll glow effect on Android or the rubber-banding effect on iOS, both of which serve as a visual indicator that the user has hit a scroll boundary. You may also see other implementations in the wild, like a “bounce” effect on mobile browsers or a page refresh when the top or bottom of a page is reached.

Syntax

overscroll-behavior: [ contain | none | auto ]{1,2}
  • Initial value: auto
  • Applies to: non-replaced block-level elements and non-replaced inline-block elements
  • Inherited: no
  • Percentages: n/a
  • Computed value: as each of the properties of the shorthand
  • Animation type: discrete

Values

/* Keyword values */
overscroll-behavior: auto; /* default */
overscroll-behavior: contain;
overscroll-behavior: none;

/* Two values */
overscroll-behavior: none auto;
overscroll-behavior: auto contain;

/* Global values */
overscroll-behavior: inherit;
overscroll-behavior: initial;
overscroll-behavior: revert;
overscroll-behavior: unset;
  • auto: The default value. Specifies that the browser should perform the default boundary action, and makes it possible for the user to continue scrolling through a parent scroll area when the boundary of the primary scroll area has been reached. In other words, it allows scroll chaining and overscroll affordances.
  • contain: Prevents scroll chaining. Scrolls do not propagate to ancestors (the other elements in a parent container) but preserve overscroll affordances like “bounce” effects when scrolling past the end of the container in operating systems that support it.
  • none: Prevents scroll chaining and also prevents overscroll affordances. So, you won’t get that Android overscroll glow or iOS rubber-banding effect.
  • initial: Applies the property’s default setting, which is auto.
  • inherit: Adopts the overscroll-behavior value of the parent.
  • unset: Removes the current overscroll-behavior from the element.

Constituent properties

We mentioned it earlier, but over scroll-behavior is shorthand for two other CSS properties, which call the “constituent properties” of the shorthand. Let’s look at those individually.

overscroll-behavior-x

As the name suggests, the overscroll-behavior-x CSS property allows you to control the browser’s behavior when the horizontal boundary of a scrolling area is reached. So, where we can control both the horizontal and vertical over scroll behavior with overscoll-behavior alone, overscroll-behavior-x only controls the behavior in the left and right direction.

In the following demo, you can see the different behavior of browser when the value of overscroll-behavior-x is contain:

See that? When contain overscroll behavior is turned off, the whole page starts to scroll once you reach the horizontal (left and right)) scrolling boundary.

overscroll-behavior-y

The overscroll-behavior-y CSS property is just like overscroll-behavior-x but it controls the browser’s behavior when the vertical boundary of a scrolling area is reached. So, we’re talking about the top and bottom direction this time.

.modal {
  overscroll-behavior-y: contain;
}

overscroll-behavior-inline

The overscroll-behavior-inline CSS property allows you to control the browser’s behavior when the inline direction boundary of a scrolling area is reached.

overscroll-behavior-inline is a CSS logical property that corresponds to the overscroll-behavior-x of an element when the writing-mode is horizontal, or the overscroll-behavior-y of the element when the writing-mode is vertical.

overscroll-behavior-block

The overscroll-behavior-block CSS property allows you to control the browser’s behavior when the block direction boundary of a scrolling area is reached.

overscroll-behavior-block is a CSS logical property that corresponds to the overscroll-behavior-y of an element when the writing-mode is horizontal, or the overscroll-behavior-x of the element when the writing-mode is vertical.

.element {
  overscroll-behavior-block: none;
}

Usage

Wanna see a few examples of overscroll-behavior in action? Of course you do!

Disabling the pull-to-refresh feature

Once the pull-to-refresh effect got very popular, mobile browsers, including Chrome on Android, implemented it as well. Swiping down at the top of the page refreshes the entire page.

Credit: Chrome Developers

As useful as this gesture is, sometimes you want to create your own pull-to-refresh effect, and need to disable the browser’s native overscroll action. We can make that happen by preventing scroll chaining on <html> or <body>:

html {
  overscroll-behavior-y: contain;
}

This also prevents overscroll navigation actions.

Credit: Chrome Developers

Disabling overscroll glow and rubber-banding effects

Setting the contain value doesn’t remove these effects. For this to work, we need to use the none value, which also disables the pull-to-refresh and overscroll navigation actions.

html {
  overscroll-behavior-y: none;
}

You might also want to use this with infinite scrolling. It might be confusing when a user reaches the bottom of page, gets a rubber-banding effect, then more content loads.

Preventing page content from scrolling underneath a modal or a fixed side navigation

Consider a side navigation with a large number of items — so many that the height of the navigation exceeds the page height and the user has to scroll down to see all of the menu items.

The overflow container stops scrolling when they reach the bottom, but if the user keeps scrolling, the rest of the content outside the navigation container starts scrolling as well.

Using contain keyword prevents this:

We can use the same approach for modals:

Browser support

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
6559117916.0

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12312412316.0

More information