Back

So verhindern Sie das Scrollen einer Seite, während ein Dialog geöffnet ist

So verhindern Sie das Scrollen einer Seite, während ein Dialog geöffnet ist

Das Öffnen eines modalen Dialogs sollte die Aufmerksamkeit des Benutzers auf diesen Dialog lenken – und nicht das Scrollen der Seite im Hintergrund erlauben. Dennoch bleibt das Verhindern des Hintergrund-Scrollens überraschend schwierig, insbesondere wenn Sie ein zuverlässiges iOS Safari Scroll-Lock-Verhalten benötigen.

Das <dialog>-Element mit showModal() blockiert Interaktionen automatisch. Der Browser markiert alles außerhalb des Dialogs als inert, wodurch Klicks und Tastaturnavigation verhindert werden. Aber die Scroll-Verhinderung? Das ist ein separates Problem, das die Plattform nicht vollständig löst.

Dieser Artikel behandelt die wichtigsten Ansätze für Scroll-Lock-Modal-Dialog-Implementierungen, ihre Kompromisse und warum keine einzelne Lösung überall perfekt funktioniert.

Wichtigste Erkenntnisse

  • Die showModal()-Methode blockiert Interaktionen, verhindert aber nicht das Hintergrund-Scrollen
  • CSS overflow: hidden funktioniert auf Desktop-Geräten, versagt aber bei iOS Safari
  • Die Fixed-Body-Technik mit Wiederherstellung der Scroll-Position bietet die zuverlässigste browserübergreifende Lösung
  • Verwenden Sie overscroll-behavior: contain zusammen mit anderen Methoden, um Scroll-Chaining zu verhindern
  • Halten Sie Ihren Dialog immer mit max-height und overflow-y: auto scrollbar, um die Barrierefreiheit zu gewährleisten

Was showModal() tut und was nicht

Wenn Sie dialog.showModal() aufrufen, führt der Browser Folgendes aus:

  • Zeigt den Dialog in der obersten Ebene an
  • Erstellt ein ::backdrop-Pseudoelement
  • Macht Hintergrundinhalte inert (blockiert Zeiger- und Tastaturinteraktionen)
  • Fängt den Fokus innerhalb des Dialogs ab

Was es nicht tut: das Hintergrund-Scrollen zuverlässig über alle Browser und Geräte hinweg verhindern. Auf einigen Plattformen – insbesondere auf mobilen Geräten – können Benutzer die Seite weiterhin mit Touch-Gesten oder Scrollrädern scrollen.

Der einfache CSS-Ansatz: overflow: hidden

Die gängigste Lösung verwendet den :has()-Selektor, um einen geöffneten Dialog zu erkennen:

body:has(dialog[open]) {
  overflow: hidden;
}

Dies funktioniert auf den meisten Desktop-Browsern. Die Seite wird nicht scrollbar, während der Dialog geöffnet ist.

Der Haken: Dieser Ansatz ist bei iOS Safari unzuverlässig. Touch-Scrolling umgeht oft overflow: hidden auf dem Body, sodass Benutzer trotzdem den Hintergrund scrollen können. Wenn Ihre Zielgruppe mobile Safari-Benutzer umfasst, benötigen Sie etwas Robusteres.

Die Fixed-Body-Technik für browserübergreifende Zuverlässigkeit

Die zuverlässigste browserübergreifende Lösung – einschließlich iOS Safari Scroll-Lock – verwendet JavaScript, um den Body zu fixieren:

let scrollPosition = 0;

function lockScroll() {
  scrollPosition = window.scrollY;
  document.body.style.position = 'fixed';
  document.body.style.top = `-${scrollPosition}px`;
  document.body.style.width = '100%';
}

function unlockScroll() {
  document.body.style.position = '';
  document.body.style.top = '';
  document.body.style.width = '';
  window.scrollTo(0, scrollPosition);
}

Rufen Sie lockScroll() beim Öffnen des Dialogs und unlockScroll() beim Schließen auf.

Diese Technik speichert die Scroll-Position, fixiert den Body, sodass er nicht scrollen kann, und stellt dann beim Schließen alles wieder her. Sie funktioniert bei Touch-Scrolling auf iOS, weil der Body sich buchstäblich nicht bewegen kann.

Kompromiss: Sie können einen Layout-Shift sehen, wenn die Scrollleiste verschwindet. Kompensieren Sie dies, indem Sie beim Sperren ein padding-right hinzufügen, das der Breite der Scrollleiste entspricht.

CSS overscroll-behavior für Scroll-Chaining

Die overscroll-behavior-Eigenschaft verhindert Scroll-Chaining – wenn das Scrollen innerhalb eines Elements dazu führt, dass ein übergeordnetes Element scrollt, nachdem die Grenze erreicht wurde.

dialog {
  overscroll-behavior: contain;
}

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

Neuere Chromium-Versionen (Ende 2025+) haben dieses Verhalten verbessert, sodass es sogar bei nicht scrollbaren Containern funktioniert. Dies hilft beim HTML-Dialog-Scroll-Locking in Chrome, aber andere Browser haben noch nicht vollständig aufgeholt.

Wichtig: CSS-overscroll-behavior-Modal-Lösungen verhindern Scroll-Chaining, nicht das Scrollen selbst. Wenn der Benutzer direkt auf dem Backdrop oder Body scrollt, stoppt overscroll-behavior dies nicht. Verwenden Sie dies zusammen mit anderen Techniken, nicht als Ersatz.

iOS Safari-Eigenheiten, die Sie kennen sollten

iOS Safari stellt einzigartige Herausforderungen für das Verhindern von Hintergrund-Scrollen in modalen Implementierungen dar:

  • overflow: hidden auf dem Body blockiert Touch-Scrolling nicht zuverlässig
  • Der Gummiband-Overscroll-Effekt kann Hintergrundbewegungen auslösen
  • Das Erscheinen der virtuellen Tastatur kann unerwartetes Scroll-Verhalten verursachen

Die Fixed-Body-Technik bleibt die zuverlässigste Lösung. Einige Entwickler fügen auch touch-action: none zum Backdrop-Element hinzu (nicht zum Dialog selbst), obwohl dies das Scrollen innerhalb des Dialogs beeinträchtigen kann, wenn es zu breit angewendet wird.

Halten Sie Ihren Dialog scrollbar

Ein kritisches Detail: Wenn Ihr Dialog-Inhalt die Viewport-Höhe überschreitet, muss der Dialog selbst scrollbar sein. Setzen Sie geeignete max-height und overflow-y: auto auf dem Dialog:

dialog {
  max-height: 90vh;
  overflow-y: auto;
}

Das Blockieren allen Scrollens schafft Barrierefreiheitsprobleme. Benutzer müssen auf alle Dialog-Inhalte zugreifen können.

Ein Hinweis zur Popover-API

Die Popover-API existiert für leichtgewichtige Overlays, ist aber kein direkter Ersatz für modale Dialoge. Popovers blockieren Hintergrundinteraktionen nicht auf die gleiche Weise, und das Scroll-Locking-Verhalten unterscheidet sich. Für echte modale Erlebnisse, die Scroll-Lock erfordern, bleiben Sie bei <dialog> und showModal().

Wahl Ihres Ansatzes

Für reine Desktop-Anwendungen reicht der CSS-:has()-Ansatz mit overflow: hidden oft aus. Für browserübergreifende Zuverlässigkeit – insbesondere iOS Safari – verwenden Sie die Fixed-Body-Technik mit Wiederherstellung der Scroll-Position. Ergänzen Sie dies mit overscroll-behavior: contain, um Scroll-Chaining in unterstützenden Browsern zu verhindern.

Fazit

Keine Lösung funktioniert überall perfekt. Die Fixed-Body-Technik bietet das zuverlässigste browserübergreifende Scroll-Locking, insbesondere für iOS Safari. Kombinieren Sie sie mit overscroll-behavior: contain für zusätzlichen Schutz gegen Scroll-Chaining in Chromium-Browsern. Testen Sie auf echten Geräten, insbesondere iOS Safari, und akzeptieren Sie, dass einige Sonderfälle möglicherweise Kompromisse erfordern.

Häufig gestellte Fragen (FAQs)

iOS Safari behandelt Touch-Scrolling anders als Desktop-Browser. Das Touch-Event-System des Browsers kann overflow hidden auf dem Body-Element umgehen und ermöglicht Hintergrund-Scrollen, selbst wenn die Eigenschaft gesetzt ist. Die Fixed-Body-Technik funktioniert, weil sie den Body physisch außerhalb des Bildschirms positioniert, wodurch Scrollen unmöglich wird, anstatt nur versteckt zu sein.

Ja, das kann sie. Wenn die Scrollleiste verschwindet, kann der Inhalt sich verschieben, um diesen Platz zu füllen. Um dies zu verhindern, berechnen Sie die Breite der Scrollleiste und fügen Sie beim Sperren des Scrollens ein entsprechendes padding-right zum Body hinzu. Entfernen Sie das Padding beim Entsperren. Dies erhält ein konsistentes Layout während der gesamten modalen Interaktion.

Die Popover-API dient einem anderen Zweck. Sie erstellt leichtgewichtige Overlays, ohne Hintergrundinteraktionen zu blockieren oder die gleichen Scroll-Locking-Fähigkeiten bereitzustellen. Für echte modale Erlebnisse, bei denen Benutzer mit dem Dialog interagieren müssen, bevor sie fortfahren können, verwenden Sie das dialog-Element mit showModal für ordnungsgemäßes Focus-Trapping und inert-Verhalten.

Setzen Sie overscroll-behavior contain auf dem Dialog, um Scroll-Chaining zum Hintergrund zu verhindern. Stellen Sie sicher, dass Ihr Dialog max-height und overflow-y auto hat, damit interner Inhalt ordnungsgemäß scrollt. Vermeiden Sie es, touch-action none auf den gesamten Dialog anzuwenden, da dies legitimes Scrollen innerhalb des modalen Inhaltsbereichs blockiert.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay