CSS :has Pseudo-class for Modal Scroll Locking

This article shows how to lock page scrolling when a modal is open by using the new CSS :has pseudo‑class—replacing JavaScript‑driven overflow toggles that fail with nested dialogs—and demonstrates a simple body:has(dialog[open]) selector that works across all modern browsers.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
CSS :has Pseudo-class for Modal Scroll Locking

Sharing a CSS tip for web developers.

In everyday development, a common issue is that when a modal dialog is opened, the background page can still be scrolled. This article explores solutions to lock page scrolling when a modal is active.

1. Traditional Implementation

The traditional approach is to prevent scrolling when the modal opens by changing the overflow property:

<span>const <span style="color: rgb(218, 208, 133)">openModal</span> = () => {</span><span>  <span style="color: rgb(198, 197, 254)">document</span>.body.style.overflow = <span style="color: rgb(168, 255, 96)">'hidden'</span></span><span>}</span><span> </span><span>const <span style="color: rgb(218, 208, 133)">closeModal</span> = () => {</span><span>  <span style="color: rgb(198, 197, 254)">document</span>.body.style.overflow = <span style="color: rgb(168, 255, 96)">'auto'</span></span><span>}</span>

In modern frameworks like vue, you can use a watcher to monitor modal state:

<span><span style="color: rgb(218, 208, 133)">watch</span>(</span><span>  () => show.value,</span><span>  (val) => {</span><span>    <span style="color: rgb(150, 203, 254)">if</span> (val) {</span><span>      <span style="color: rgb(198, 197, 254)">document</span>.body.style.overflow = <span style="color: rgb(168, 255, 96)">'hidden'</span></span><span>    } <span style="color: rgb(150, 203, 254)">else</span> {</span><span>      <span style="color: rgb(198, 197, 254)">document</span>.body.style.overflow = <span style="color: rgb(168, 255, 96)">'auto'</span></span><span>    }</span><span>  },</span><span>)</span>

2. Limitations of Traditional Approach

Although the above implementation seems perfect, there are potential issues. When there are multiple modals overlapping, the locking can break. When closing the second modal, the page is already unlocked, so the first modal's background becomes scrollable.

3. Using CSS :has Pseudo-class

With the CSS :has pseudo-class, everything becomes simpler - no complex judgments needed, just one selector:

<span><span style="color: rgb(168, 255, 96)">body:has(dialog[open])</span></span><span>{</span><span>  <span style="color: rgb(150, 203, 254)">overflow</span>: hidden</span><span>}</span>

This selector means: as long as there is a modal with the open attribute, the body will automatically be locked, regardless of how many nested modals exist.

4. Full Browser Compatibility

Regarding compatibility, all modern browsers now support the :has selector.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendJavaScriptCSS:has() selectormodal dialogscroll lockweb-development
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.