防止捲動強制回應對話方塊下方的頁面

使用 showModal() 將 <dialog> 元素做為互動視窗開啟時,瀏覽器會將其升級至頂層,並將文件的其餘部分標示為惰性。雖然這會阻擋指標點擊和鍵盤焦點,但不會阻止捲動:

  1. 當指標或觸控手勢位於 ::backdrop 上方時,捲動會捲動下方的頁面。
  2. 在對話方塊中捲動時,如果對話方塊內容未溢出,或對話方塊捲動到邊界,捲動動作會鏈結到<dialog>,並套用到下方的頁面。

根據 CSS 過度捲動行為規格,overscroll-behavior 適用於「所有捲動容器元素」,包括不可捲動的捲動容器 (具有 overflow: hidden 或 overflow: auto 的元素,其內容目前不會溢位)。只要在 <dialog> 上結合 overscroll-behavior: contain,並在 dialog::backdrop 上結合 overflow: hidden 和 overscroll-behavior: contain,就能使用純 CSS 防止基礎頁面捲動。

導入作業

1. 在 <dialog> 上包含捲動鏈結

使用者代理程式樣式表會在 <dialog> 上設定 overflow: auto,預設為捲動容器。將 overscroll-behavior: contain (或 none) 套用至 dialog:modal (或 dialog)。

2. 將 ::backdrop 轉換為捲動容器,並包含其捲動

根據預設,dialog::backdrop 具有 overflow: visible,表示它「不是」捲動容器,且會忽略 overscroll-behavior。您必須在 dialog::backdrop 上設定 overflow: hidden,使其成為不可捲動的捲動容器,並與 overscroll-behavior: contain 搭配使用,這樣在背景上執行的捲動手勢就會被捕捉,不會到達下方的文件。

程式碼範例

dialog:modal {
  /* MANDATORY: Prevent scroll gestures inside the modal (even when its content
     does not overflow) from chaining to the underlying page. */
  overscroll-behavior: contain;
}

dialog::backdrop {
  /* MANDATORY: ::backdrop defaults to overflow: visible (not a scroll container).
     Set overflow: hidden so it becomes a non-scrollable scroll container that
     honors overscroll-behavior. */
  overflow: hidden;
  overscroll-behavior: contain;
}

最佳做法和限制

  • 必要:在 <dialog> 元素本身 (使用 dialog:modal 選取器) 和 dialog::backdrop 上設定 overscroll-behavior: contain。如果沒有這個宣告,在背景或對話方塊內捲動手勢仍會鏈結至頁面。
  • 必要:在 dialog::backdrop 上設定 overflow: hidden (或 overflow: auto),使其成為捲動容器。如果沒有這個宣告,::backdrop 預設為 overflow: visible,且 overscroll-behavior 不會有任何作用。
  • 請勿在 dialog::backdrop 或 dialog 上使用 overflow: clip 或 overflow: visible。這兩個值都不會建立捲動容器,因此不會套用 overscroll-behavior。
  • 請勿將 overflow: hidden 或 position: fixed 套用至 <html> 或 <body>,以免在對話方塊開啟時鎖定背景捲動功能。變更根溢位會移除頁面捲軸 (導致水平版面配置位移)、重設或跳轉頁面捲動位置,並破壞基礎頁面上的 position: sticky 元素。

備用策略

雖然所有主要瀏覽器都支援 overscroll-behavior CSS 屬性,可用於內容溢出的捲動容器,但「不可捲動」捲動容器上的 overscroll-behavior 則是較新的規格,無法偵測功能。

請勿嘗試使用 @supports (overscroll-behavior: contain) 或 CSS.supports('overscroll-behavior', 'contain') 偵測非捲動容器支援功能。所有新式瀏覽器都支援 overscroll-behavior: contain 屬性語法,並會傳回 true,即使只有在內容溢位時才會強制執行。

相反地,請將不可捲動容器的捲動限制視為漸進增強:

  • 在支援 overscroll-behavior 的瀏覽器中,如果捲動容器不可捲動,則在 dialog::backdrop 上方和 <dialog> 內部 (無論內容是否溢位),背景頁面捲動都會完全遭到禁止。
  • 在不支援非捲動容器 overscroll-behavior 的瀏覽器中,只要對話方塊本身的內容溢出且可捲動,dialog 上的 overscroll-behavior: contain 仍會防止捲動鏈結。同時,showModal() 仍會捕捉鍵盤焦點,並將背景文件標示為 inert。
  • 建議您採用漸進增強功能,而非將 overflow: hidden 或 position: fixed 套用至 <html> 或 <body> 的舊版解決方法,因為這樣不會移除根捲軸、造成水平版面配置位移、跳轉網頁捲動位置,或破壞基礎網頁上的 position: sticky 元素。