Wenn ein <dialog>-Element mit showModal() als modales Fenster geöffnet wird, verschiebt der Browser es in die oberste Ebene und markiert den Rest des Dokuments als inaktiv. Dadurch werden zwar Klicks mit dem Mauszeiger und der Tastaturfokus auf der zugrunde liegenden Seite blockiert, das Scrollen wird jedoch nicht verhindert:
- Wenn Sie scrollen, während sich der Mauszeiger oder die Touch-Geste über dem
::backdropbefindet, wird die Seite darunter gescrollt. - Wenn Sie innerhalb des
<dialog>scrollen, wird die zugrunde liegende Seite gescrollt, sobald das Dialogfeld seine Scrollgrenze erreicht – oder sofort, wenn der Inhalt des Dialogfelds nicht überläuft.
Gemäß der CSS-Spezifikation für das Overscroll-Verhalten gilt overscroll-behavior für alle Scroll-Container-Elemente, einschließlich nicht scrollbarer Scroll-Container (Elemente mit overflow: hidden oder overflow: auto, deren Inhalt derzeit nicht überläuft). Wenn Sie overscroll-behavior: contain für <dialog> mit overflow: hidden und overscroll-behavior: contain für dialog::backdrop kombinieren, können Sie verhindern, dass die zugrunde liegende Seite mit reinem CSS gescrollt wird.
Implementierung
1. Scrollverkettung auf dem <dialog>-Element eingrenzen
Das User-Agent-Stylesheet legt overflow: auto für <dialog> fest, sodass es standardmäßig ein Scrollcontainer ist. Wenden Sie overscroll-behavior: contain (oder none) auf dialog:modal (oder dialog) an.
2. ::backdrop in einen Scroll-Container umwandeln und das Scrollen darin einschränken
Standardmäßig hat dialog::backdrop den Wert overflow: visible. Das bedeutet, dass es sich nicht um einen Scrollcontainer handelt und overscroll-behavior ignoriert wird. Sie müssen overflow: hidden für dialog::backdrop festlegen, um es zu einem nicht scrollbaren Scrollcontainer zu machen, und es mit overscroll-behavior: contain kombinieren, damit Scrollgesten, die über dem Hintergrund ausgeführt werden, abgefangen werden und das darunter liegende Dokument nicht erreichen.
Beispielcode
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;
}
Best Practices und Einschränkungen
- ERFORDERLICH: Legen Sie
overscroll-behavior: containfür das<dialog>-Element selbst (mit demdialog:modal-Selektor) und für dasdialog::backdrop-Element fest. Ohne diese Deklaration werden Scroll-Gesten über dem Hintergrund oder innerhalb des Dialogfelds weiterhin mit der Seite verkettet. - ERFORDERLICH: Legen Sie
overflow: hidden(oderoverflow: auto) fürdialog::backdropfest, damit es zu einem Scrollcontainer wird. Ohne diese Deklaration wird::backdropstandardmäßig aufoverflow: visiblegesetzt undoverscroll-behaviorhat keine Auswirkungen. - Verwenden Sie NICHT
overflow: clipoderoverflow: visiblefürdialog::backdropoderdialog. Keiner der Werte legt einen Scrollcontainer fest, daher wirdoverscroll-behaviornicht angewendet. - Wenden Sie NICHT
overflow: hiddenoderposition: fixedauf<html>oder<body>an, um das Scrollen im Hintergrund zu sperren, wenn ein Dialogfeld geöffnet wird. Wenn Sie den Root-Überlauf ändern, wird die Bildlaufleiste der Seite entfernt (was zu einer horizontalen Layoutverschiebung führt), die Scrollposition der Seite kann zurückgesetzt werden oder springen undposition: sticky-Elemente auf der zugrunde liegenden Seite können beschädigt werden.
Fallback-Strategien
Die CSS-Eigenschaft overscroll-behavior wird in allen gängigen Browsern für Scrollcontainer mit überlaufendem Inhalt unterstützt. Die Berücksichtigung von overscroll-behavior bei nicht scrollbaren Scrollcontainern ist jedoch eine neuere Spezifikation, die nicht per Feature-Erkennung erkannt werden kann.
Versuchen Sie NICHT, die Unterstützung für nicht scrollbare Container mit @supports (overscroll-behavior: contain) oder CSS.supports('overscroll-behavior', 'contain') zu erkennen. Alle modernen Browser unterstützen die Syntax des Attributs overscroll-behavior: contain und geben true zurück, auch wenn sie es nur bei einem Überlauf von Inhalten erzwingen.
Behandeln Sie die Scroll-Eingrenzung bei nicht scrollbaren Scroll-Containern stattdessen als progressive Verbesserung:
- In Browsern, die
overscroll-behaviorfür nicht scrollbare Scrollcontainer unterstützen, wird das Scrollen der Hintergrundseite sowohl überdialog::backdropals auch innerhalb des<dialog>vollständig verhindert, unabhängig davon, ob der Inhalt überläuft oder nicht. - In Browsern, die
overscroll-behaviorfür nicht scrollbare Scrollcontainer noch nicht unterstützen, verhindertoverscroll-behavior: containfürdialogweiterhin die Scrollverkettung, wenn der Inhalt des Dialogfelds überläuft und scrollbar ist. In der Zwischenzeit wird der Tastaturfokus weiterhin vonshowModal()abgefangen und das Hintergrunddokument alsinertmarkiert. - Die progressive Verbesserung wird gegenüber Legacy-Problemumgehungen empfohlen, bei denen
overflow: hiddenoderposition: fixedauf<html>oder<body>angewendet wird, da die Stamm-Scrollleiste nicht entfernt wird, keine horizontalen Layoutverschiebungen verursacht werden, die Scrollposition der Seite nicht springt undposition: sticky-Elemente auf der zugrunde liegenden Seite nicht beschädigt werden.