Use overscroll-behavior: contain to prevent a page from scrolling while a <dialog> is open

Chrome 144 features a small change to overscroll-behavior: it now also works on non-scrollable scroll containers. While this change might seem trivial, it fixes an issue developers have been dealing with for ages: prevent a page from scrolling while a (modal) <dialog> is open.

~

CSS overscroll-behavior – which I first covered here in 2017 – allows you to control what a browser should do when reaching the boundary of a scrolling area.

For example, if you set it to overscroll-behavior: contain, it will prevent scroll chaining from happening, so that underlying elements don’t scroll.

~

The problem with overscroll-behavior is that it only works when the scroll container is actually scrollable. For example, if you set overscroll-behavior: contain on a <dialog> that doesn’t scroll, then overscroll-behavior won’t do anything. There must at least be 1 pixel of overflow before overscroll-behavior kicks in.

In Chrome 144 this changed, and overscroll-behavior now also works on non-scrollable scroll containers, as intended by the specification. A non-scrollable scroll container gets created when you set overflow: auto but there is no overflow, or when using overflow: hidden.

~

While this change might go unnoticed at first, it unlocks a problem developers have been having for a long time: prevent a page from scrolling when a (modal) <dialog> is open. In Chrome 144+, all it takes is this CSS snippet:

dialog {
	overscroll-behavior: contain;
}

dialog::backdrop {
	overflow: hidden;
	overscroll-behavior: contain;
}

The key to the code is the overflow: hidden; that you must set on the ::backdrop, as that makes it a (non-scrollable) scroll container.

Try it out in this demo (in Chrome 144+):

(If the page is scrolling underneath the open <dialog>, you are not using Chrome 144+ ;))

I hope that other browser vendors follow suit here, as this solves a real problem developers have been struggling with, and setting overflow: hidden on html as a workaround ain’t exactly cutting it.

For reference, here’s the Gecko/Firefox Bug and the WebKit/Safari Bug.

~

🔥 Like what you see? Want to stay in the loop? Here's how:

I can also be found on 𝕏 Twitter and 🐘 Mastodon but only post there sporadically.

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Unless noted otherwise, the contents of this post are licensed under the Creative Commons Attribution 4.0 License and code samples are licensed under the MIT License

Join the Conversation

1 Comment

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.