J'ai cherché une solution de type "lightbox" qui le permet mais je n'en ai pas encore trouvé (veuillez suggérer si vous en connaissez).
Le comportement que j'essaie de recréer est similaire à ce que vous verriez sur Pinterest en cliquant sur une image. La superposition peut défiler ( comme dans toute la superposition monte comme une page en haut d'une page ) mais le corps derrière la superposition est fixe.
J'ai essayé de créer cela avec seulement CSS ( c'est-à-dire une div
superposition au-dessus de la page entière et du corps avecoverflow: hidden
), mais cela n'empêche pas le div
défilement.
Comment empêcher le corps / la page de défiler mais continuer à défiler à l'intérieur du conteneur plein écran?
Réponses:
Théorie
En regardant l'implémentation actuelle du site pinterest (cela pourrait changer à l'avenir), lorsque vous ouvrez la superposition, une
noscroll
classe est appliquée à l'body
élément etoverflow: hidden
est définie, ellebody
n'est donc plus défilable.La superposition (créé sur la volée ou déjà à l' intérieur de la page et rendu visible par l' intermédiaire
display: block
, il ne fait aucune différence) aposition : fixed
etoverflow-y: scroll
, avectop
,left
,right
etbottom
définir les propriétés à0
: ce style fait de la superposition remplir toute la fenêtre.L'
div
intérieur de la superposition est à la place juste à l'intérieur,position: static
puis la barre de défilement verticale que vous voyez est liée à cet élément. En conséquence, le contenu peut défiler mais la superposition reste fixe.Lorsque vous fermez le zoom, vous masquez la superposition (via
display: none
) et vous pouvez également la supprimer entièrement via javascript (ou simplement le contenu à l'intérieur, c'est à vous de l'injecter).Comme dernière étape, vous devez également supprimer la
noscroll
classe dans lebody
(afin que la propriété overflow revienne à sa valeur initiale)Code
(cela fonctionne en changeant l'
aria-hidden
attribut de la superposition afin de l'afficher et de la cacher et d'augmenter son accessibilité).Marquage
(bouton ouvert)
(bouton de superposition et de fermeture)
CSS
Javascript (vanille-JS)
Enfin, voici un autre exemple dans lequel la superposition s'ouvre avec un effet de fondu par un CSS
transition
appliqué à laopacity
propriété. Unpadding-right
est également appliqué pour éviter une redistribution sur le texte sous-jacent lorsque la barre de défilement disparaît.CSS
la source
div
doit avoir un style CSSposition:fixed
et un débordement vertical pouvant défiler. J'ai utilisé avec succèsoverflow-y:auto;
et pour le défilement momentum / inertie iOS, j'ai ajouté-webkit-overflow-scrolling:touch;
au CSS. J'utilisédisplay:block;
,width:100%;
etheight:100%;
CSS pour avoir une fenêtre pleine page.Si vous souhaitez empêcher le défilement excessif sur iOS, vous pouvez ajouter une position fixée à votre classe .noscroll
la source
position:fixed
est qu'elle redimensionnait mon corps principal. Peut-être qu'il était en conflit avec d'autres CSS, maisoverflow:hidden
c'est tout ce qui était nécessaireNe pas utiliser
overflow: hidden;
surbody
. Il fait automatiquement défiler tout vers le haut. Il n'y a pas non plus besoin de JavaScript. Faites usage deoverflow: auto;
. Cette solution fonctionne même avec Safari mobile:Structure HTML
Coiffant
Voir la démo ici et le code source ici .
Mise à jour:
Pour les personnes qui souhaitent que la barre d'espace du clavier fonctionne, la page haut / bas fonctionne: vous devez vous concentrer sur la superposition, par exemple en cliquant dessus ou manuellement JS en se concentrant dessus avant que cette partie du
div
ne réponde au clavier. Même chose lorsque la superposition est "désactivée", car elle déplace simplement la superposition sur le côté. Sinon pour le navigateur, ce ne sont que deuxdiv
s normaux et il ne saurait pas pourquoi il devrait se concentrer sur l'un d'eux.la source
html, body { height: 100%; }
(comme dans la démo) pour que cela fonctionne correctement..offset()
valeurs pour le calcul est foiré, etc ...overscroll-behavior
La propriété css permet de remplacer le comportement de défilement par défaut du navigateur pour atteindre le haut / bas du contenu.Ajoutez simplement les styles suivants à la superposition:
Fonctionne actuellement dans Chrome, Firefox et IE ( caniuse )
Pour plus de détails, consultez l' article des développeurs Google .
la source
overflow-y: scroll
(de votre démo Codepen). Le point soulevé par @pokrishka est valide, mais dans mon cas, ce n'est pas un problème. Dans tous les cas, je me demande si les implémentations des navigateurs vont couvrir ce détail à l'avenir. J'ai trouvé que, dans Firefox, redimensionner le navigateur pour que le modal ne s'adapte pas à l'écran, puis le redimensionner à nouveau pour qu'il fasse fonctionner cette propriété (c'est-à-dire que le défilement est contenu) même après avoir redimensionné en taille réelle - jusqu'à ce que la page soit rechargée , au moins.La plupart des solutions ont le problème de ne pas conserver la position de défilement, j'ai donc regardé comment Facebook le fait. En plus de définir le contenu sous-jacent,
position: fixed
ils définissent également le haut de manière dynamique pour conserver la position de défilement:Ensuite, lorsque vous supprimez à nouveau la superposition, vous devez réinitialiser la position de défilement:
J'ai créé un petit exemple pour démontrer cette solution
la source
Il convient de noter que parfois, l'ajout de "débordement: caché" à la balise body ne fait pas le travail. Dans ces cas, vous devrez également ajouter la propriété à la balise html.
la source
width: 100%; height: 100%;
De manière générale, si vous souhaitez qu'un parent (le corps dans ce cas) l'empêche de défiler lorsqu'un enfant (la superposition dans ce cas) défile, faites de l'enfant un frère du parent pour empêcher l'événement de défilement de se propager jusqu'à le parent. Dans le cas où le parent est le corps, cela nécessite un élément d'habillage supplémentaire:
Voir Faire défiler des contenus DIV particuliers avec la barre de défilement principale du navigateur pour voir son fonctionnement.
la source
La réponse choisie est correcte, mais présente certaines limites:
<body>
en arrière-plan<input>
dans le modal dirigera tous les futurs parchemins vers<body>
Je n'ai pas de solution pour le premier problème, mais je voulais faire la lumière sur le second. Confusément, Bootstrap avait l'habitude de documenter le problème de clavier, mais ils ont prétendu qu'il était corrigé, citant http://output.jsbin.com/cacido/quiet comme exemple de la correction.
En effet, cet exemple fonctionne très bien sur iOS avec mes tests. Cependant, sa mise à niveau vers le dernier Bootstrap (v4) le casse.
Afin de comprendre quelle était la différence entre eux, j'ai réduit un cas de test pour ne plus dépendre de Bootstrap, http://codepen.io/WestonThayer/pen/bgZxBG .
Les facteurs décisifs sont bizarres. Pour éviter le problème du clavier, il semble qu'il
background-color
ne soit pas défini sur la racine<div>
contenant le modal et que le contenu du modal doit être imbriqué dans un autre<div>
, qui peut avoir étébackground-color
défini.Pour le tester, décommentez la ligne ci-dessous dans l'exemple Codepen:
la source
Pour les appareils tactiles, essayez d'ajouter une
101vh
div transparente de 1px de largeur et de hauteur minimale dans le wrapper de la superposition. Ajoutez ensuite-webkit-overflow-scrolling:touch; overflow-y: auto;
à l'emballage. Cela incite le safari mobile à penser que la superposition peut défiler, interceptant ainsi l'événement tactile du corps.Voici un exemple de page. Ouvert sur safari mobile: http://www.originalfunction.com/overlay.html
https://gist.github.com/YarGnawh/90e0647f21b5fa78d2f678909673507f
la source
-webkit-overflow-scrolling:touch;
pour chaque conteneur déroulant pour intercepter les événements tactiles.Le comportement que vous souhaitez empêcher est appelé chaînage de défilement. Pour le désactiver, définissez
sur votre superposition en CSS.
la source
J'ai trouvé cette question en essayant de résoudre le problème que j'avais avec ma page sur Ipad et Iphone - le corps défilait lorsque j'affichais un div fixe sous forme de popup avec image.
Certaines réponses sont bonnes, mais aucune n'a résolu mon problème. J'ai trouvé le billet de blog suivant de Christoffer Pettersson. La solution présentée ici a aidé à résoudre le problème que j'avais avec les appareils iOS et à résoudre mon problème d'arrière-plan de défilement.
Six choses que j'ai apprises sur le défilement de l'élastique sur iOS Safari
Comme il a été suggéré, j'inclus les principaux points de l'article de blog au cas où le lien deviendrait obsolète.
"Afin de désactiver le fait que l'utilisateur puisse faire défiler la page d'arrière-plan pendant que le" menu est ouvert ", il est possible de contrôler quels éléments doivent être autorisés à faire défiler ou non, en appliquant du JavaScript et une classe CSS.
Sur la base de cette réponse Stackoverflow, vous pouvez contrôler que les éléments avec la désactivation du défilement ne doivent pas effectuer leur action de défilement par défaut lorsque l'événement touchmove est déclenché. "
Et puis mettez la classe disable-scrolling sur la page div:
la source
Vous pouvez facilement le faire avec certains "nouveaux" CSS et JQuery.
Initialement:
body {... overflow:auto;}
Avec JQuery, vous pouvez basculer dynamiquement entre «superposition» et «corps». Lorsque sur «corps», utilisezEn utilisation "superposition"
JQuery pour le commutateur ('body' -> 'overlay'):
JQuery pour le commutateur ('overlay' -> 'body'):
la source
Je voudrais ajouter aux réponses précédentes parce que j'ai essayé de le faire, et une disposition s'est cassée dès que j'ai changé le corps en position: fixe. Pour éviter cela, j'ai également dû régler la taille du corps à 100%:
la source
Utilisez le code HTML suivant:
Ensuite, JavaScript pour intercepter et arrêter le défilement:
Ensuite, pour ramener les choses à la normale:
$(".page").off("touchmove");
la source
Si l'intention est de désactiver sur les appareils mobiles / tactiles, la façon la plus simple de le faire est d'utiliser
touch-action: none;
.Exemple:
(L'exemple ne fonctionne pas dans le contexte de débordement de pile. Vous devrez le recréer dans une page autonome.)
Si vous souhaitez désactiver le défilement du
#app
conteneur, ajoutez simplementtouch-action: none;
.la source
essaye ça
la source
Si vous souhaitez arrêter le défilement body / html, ajoutez comme suit
CSS
HTML
Fondamentalement, vous pourriez le faire sans JS.
L'idée principale est d'ajouter html / body avec hauteur: 100% et débordement: auto. et à l'intérieur de votre superposition, vous pouvez soit activer / désactiver le défilement en fonction de vos besoins.
J'espère que cela t'aides!
la source
Dans mon cas, aucune de ces solutions n'a fonctionné sur iPhone (iOS 11.0).
Le seul correctif efficace qui fonctionne sur tous mes appareils est celui-ci - ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintenir-scroll-position
la source
Utilisez le code ci-dessous pour désactiver et activer la barre de défilement.
la source