Lorsqu'un élément <dialog> est ouvert en tant que boîte de dialogue modale à l'aide de showModal(), le navigateur le place dans la couche supérieure et marque le reste du document comme inerte. Bien que cela bloque les clics du pointeur et le focus clavier sur la page sous-jacente, cela n'empêche pas le défilement :
- Si vous faites défiler la page alors que le pointeur ou le geste tactile se trouve sur l'élément
::backdrop, la page défile en dessous. - Le défilement dans le
<dialog>est lié à la page sous-jacente une fois que la boîte de dialogue atteint sa limite de défilement, ou immédiatement si le contenu de la boîte de dialogue ne dépasse pas.
Conformément à la spécification CSS Overscroll Behavior, overscroll-behavior s'applique à tous les éléments de conteneur de défilement, y compris les conteneurs de défilement non défilables (éléments avec overflow: hidden ou overflow: auto dont le contenu ne déborde pas actuellement). En combinant overscroll-behavior: contain sur <dialog> avec overflow: hidden et overscroll-behavior: contain sur dialog::backdrop, vous pouvez empêcher le défilement de la page sous-jacente en utilisant uniquement du CSS.
Implémentation
1. Contenir le chaînage de défilement sur <dialog>
La feuille de style user-agent définit overflow: auto sur <dialog>, ce qui en fait un conteneur de défilement par défaut. Appliquez overscroll-behavior: contain (ou none) à dialog:modal (ou dialog).
2. Transformer ::backdrop en conteneur de défilement et contenir son défilement
Par défaut, dialog::backdrop est défini sur overflow: visible, ce qui signifie qu'il ne s'agit pas d'un conteneur de défilement et qu'il ignore overscroll-behavior. Vous devez définir overflow: hidden sur dialog::backdrop pour en faire un conteneur de défilement non déroulant, et l'associer à overscroll-behavior: contain afin que les gestes de défilement effectués sur l'arrière-plan soient interceptés et n'atteignent pas le document sous-jacent.
Exemple de code
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;
}
Bonnes pratiques et contraintes
- OBLIGATOIRE : définissez
overscroll-behavior: containsur l'élément<dialog>lui-même (à l'aide du sélecteurdialog:modal) et surdialog::backdrop. Sans cette déclaration, les gestes de défilement sur l'arrière-plan ou dans la boîte de dialogue seront toujours associés à la page. - OBLIGATOIRE : Définissez
overflow: hidden(ouoverflow: auto) surdialog::backdroppour qu'il devienne un conteneur de défilement. Sans cette déclaration,::backdropest défini par défaut suroverflow: visibleetoverscroll-behaviorn'aura aucun effet. - N'UTILISEZ PAS
overflow: clipouoverflow: visiblesurdialog::backdropoudialog. Aucune de ces valeurs n'établit de conteneur de défilement.overscroll-behaviorne s'appliquera donc pas. - N'appliquez PAS
overflow: hiddenouposition: fixedà<html>ou<body>pour verrouiller le défilement en arrière-plan lorsqu'une boîte de dialogue s'ouvre. La modification du dépassement de la racine supprime la barre de défilement de la page (ce qui entraîne un décalage de la mise en page horizontale), peut réinitialiser ou faire sauter la position de défilement de la page, et peut endommager les élémentsposition: stickyde la page sous-jacente.
Stratégies de remplacement
Bien que la propriété CSS overscroll-behavior soit compatible avec tous les principaux navigateurs pour les conteneurs de défilement dont le contenu dépasse, le respect de overscroll-behavior sur les conteneurs de défilement non défilables est une spécification plus récente qui ne peut pas être détectée par les fonctionnalités.
N'essayez PAS de détecter la compatibilité avec les conteneurs non déroulants à l'aide de @supports (overscroll-behavior: contain) ou CSS.supports('overscroll-behavior', 'contain'). Tous les navigateurs récents sont compatibles avec la syntaxe de la propriété overscroll-behavior: contain et renvoient true, même s'ils ne l'appliquent que lorsque le contenu déborde.
Traitez plutôt le confinement du défilement sur les conteneurs de défilement non défilables comme une amélioration progressive :
- Dans les navigateurs compatibles avec
overscroll-behaviorsur les conteneurs de défilement non défilables, le défilement de la page en arrière-plan est complètement empêché à la fois surdialog::backdropet à l'intérieur de<dialog>(que son contenu déborde ou non). - Dans les navigateurs qui ne sont pas encore compatibles avec
overscroll-behaviorsur les conteneurs de défilement non défilables,overscroll-behavior: containsurdialogempêche toujours le chaînage du défilement lorsque le contenu de la boîte de dialogue dépasse et est défilable. Pendant ce temps,showModal()piège toujours le focus clavier et marque le document d'arrière-planinert. - Il est recommandé de s'appuyer sur l'amélioration progressive plutôt que sur les anciennes solutions de contournement qui appliquent
overflow: hiddenouposition: fixedà<html>ou<body>, car cela ne supprime pas la barre de défilement racine, ne provoque pas de décalages de mise en page horizontaux, ne fait pas sauter la position de défilement de la page et ne casse pas les élémentsposition: stickyde la page sous-jacente.