Overflow-x: hidden n'empêche pas le contenu de déborder dans les navigateurs mobiles

142

J'ai un site Web ici .

Vue dans un navigateur de bureau, la barre de menu noire ne s'étend correctement que jusqu'au bord de la fenêtre, puisque le bodyhas overflow-x:hidden.

Dans n'importe quel navigateur mobile, qu'il soit Android ou iOS, la barre de menu noire affiche toute sa largeur, ce qui amène des espaces à droite de la page. Pour autant que je sache, cet espace ne fait même pas partie des balises htmlou body.

Même si je règle la fenêtre sur une largeur spécifique dans <head>:

<meta name="viewport" content="width=1100, initial-scale=1">

Le site se développe au 1100px mais a toujours l'espace blanc au-delà du 1100.

Qu'est-ce que je rate? Comment conserver la fenêtre d'affichage à 1100 et couper le débordement?

Indigénité
la source
1
C'est particulièrement un problème dans iOS9
Chuck Le Butt

Réponses:

270

La création d'un div wrapper de site à l'intérieur de <body>et l'application overflow-x:hiddendu wrapper au lieu de <body>ou ont <html>résolu le problème.

Il semble que les navigateurs qui analysent la <meta name="viewport">balise ignorent simplement les overflowattributs des balises htmlet body.

Remarque: vous devrez peut-être également ajouter position: relativeau div wrapper.

Indigénité
la source
44
J'ai trouvé qu'en plus de régler le overflowsur hidden, je devais régler le positionsur fixed...
Victor S
16
L'ajout de position à fixe m'empêche de pouvoir faire défiler!
théoriser
5
J'ai essayé, j'ai mis tout mon code dans un div et lui donne overflow-x: hidden mais ne fonctionne pas, j'ajoute <meta name = "viewport" content = "width = device-width, initial-scale = 1"> aussi mais rien n'a changé: / des idées?
4
@leepowers overflow-x: hiddenne fonctionne toujours pas pour moi même après avoir ajouté cette balise meta. Pourriez-vous s'il vous plaît partager un lien vers votre site Web où il fonctionne?
jupiteror
3
Hé gang, quand j'ai trouvé que ça position:relativemarche aussi.
Thomas Valadez
80

essayer

html, body {
  overflow-x:hidden 
} 

au lieu de juste

body {
  overflow-x:hidden 
}
sous-arachnide
la source
7
Merci, mais l'application de overflowquoi que ce soit à htmlet / ou bodydans n'importe quelle combinaison n'a pas résolu le problème.
Indigenuity
Désolé que cela n'ait pas fonctionné pour vous. Avant de répondre, j'ai fait un test rapide en utilisant votre site et en appliquant ma suggestion à votre css. Cela a résolu le problème du navigateur standard et Dolphin sur mon téléphone Android au moins.
subarachnid
3
A travaillé pour moi. eduardd.eu/projects/ezo (entre 480 et 992px le pied de page avait un problème avec cette image débordante de la femme et des serviettes)
Eduard
2
Est-ce que quelqu'un sait pourquoi cela fonctionne, lorsque la spécification de body {} et html {} séparément ne fonctionne pas?
hamncheez
1
Il est également nécessaire d'ajouter height:100%;, sinon le défilement vertical ne fonctionnerait pas correctement sur les pages avec des images de chargement (ce qui fait grossir la page).
Arno van Oordt
69

Le commentaire de VictorS sur la réponse acceptée mérite d'être sa propre réponse car c'est une solution très élégante qui fonctionne, en effet. Et j'ajouterai un peu à son utilité.

Victor note l'ajout d' position:fixedœuvres.

body.modal-open {
    overflow: hidden;
    position: fixed;
}

Et c'est effectivement le cas. Cependant, il a également un léger effet secondaire consistant essentiellement à faire défiler vers le haut. position:absoluterésout ce problème, mais réintroduit la possibilité de faire défiler sur mobile.

Si vous connaissez votre fenêtre d'affichage ( mon plugin pour ajouter une fenêtre d'affichage au<body> ), vous pouvez simplement ajouter une bascule css pour le position.

body.modal-open {
    // block scroll for mobile;
    // causes underlying page to jump to top;
    // prevents scrolling on all screens
    overflow: hidden;
    position: fixed;
}
body.viewport-lg {
    // block scroll for desktop;
    // will not jump to top;
    // will not prevent scroll on mobile
    position: absolute; 
}

J'ajoute également ceci pour empêcher la page sous-jacente de sauter à gauche / droite lors de l'affichage / du masquage des modaux.

body {
    // STOP MOVING AROUND!
    overflow-x: hidden;
    overflow-y: scroll !important;
}
Brad
la source
2
Est-il possible de faire en sorte que la partie mobile ne saute pas en haut?
WraithKenny
1
Ce qui a fonctionné pour moi a été de faire passer l'élément censé être masqué par le débordement de la position: absolue à la position: fixe. Heureusement.
Chuck Le Butt
1
@WraithKenny - Si vous voulez que la page empêche de sauter vers le haut sur un appareil mobile, vous pouvez utiliser l'approche hack'ish / laide suivante. Dans votre fonction modale, assurez-vous d'obtenir le décalage de défilement actuel avant de faire quoi que ce soit, puis appliquez le style modal ensemble et définissez également la marge supérieure de votre corps égale au moins du décalage actuel. Assurez-vous que lorsque vous supprimez le modal vous, définissez la marge sur 0 et faites défiler la page vers le décalage d'origine.
Emil Borconi
2
Cette solution ne fonctionne que si le contenu de votre modal rentre dans l'écran, c'est-à-dire que vous n'avez pas besoin de faire défiler le modal lui-même.
Tobias
Il y a également d'autres éléments positionnés fixes et absolus sur ma page. Faire du corps position:fixed or absolutedéranger leurs positions aussi. Ne convient pas / fonctionne dans mon cas :(
sohaiby
31

C'est la solution la plus simple pour résoudre le défilement horizontal dans Safari.

html, body {
  position:relative;
  overflow-x:hidden;
}
Waltur Buerk
la source
1
Cela semble fonctionner. Mais avez-vous une explication pourquoi cela fonctionne?
LarS
Non, cela n'a finalement pas fonctionné. J'ai fini par faire le calcul et je me suis assuré que les div ne sont pas plus larges que permis, css calc () m'a beaucoup aidé ici car il permet le mélange de largeurs relatives (vw ou%) et de largeurs absolues (px).
LarS
Bien sûr, il s'agit d'une solution de contournement. Il y a encore quelque chose qui déborde quelque part, c'est juste coupé maintenant. Essayez d'ajouter une règle css: * {contour: 1px rouge fixe; } Si vous ne trouvez toujours pas l'élément débordant, c'est probablement dû à une marge quelque part. Essayez d'ajouter * {margin: 0! IMPORTANT; } et voyez si le débordement disparaît.
Waltur Buerk
Travaille pour moi. Intéressant que l'élément caché change la largeur du corps. Pour moi, cependant, c'est le cas pour TOUS les navigateurs Safari, pas seulement pour les mobiles. Juste eu à corriger un table-responsivebug Bootstrap 4 . C'était la solution.
CunningFatalist
2
Je ne peux pas croire que ce soit encore un problème en 2019. Mais la solution ci-dessus a totalement fonctionné. THX.
staxim
28

Comme l'indique @Indigenuity, cela semble être dû au fait que les navigateurs analysent la <meta name="viewport">balise.

Pour résoudre ce problème à la source, essayez ce qui suit:

<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">.

Dans mes tests, cela empêche l'utilisateur de faire un zoom arrière pour afficher le contenu débordé et, par conséquent, empêche également le panoramique / le défilement.

Tempurturtul
la source
L'ajout initial-scale=1à une méta-balise de fenêtre existante résout en effet le problème. Merci!
JamesWilson
6
Pour moi, c'est le minimum-scale=1qui l'a corrigé
jpenna
C'est ce qui a fonctionné pour moi après avoir essayé tout le reste. Merci beaucoup !
Harsh Limaye le
16
body{
height: 100%;
overflow: hidden !important;
width: 100%;
position: fixed;

fonctionne sur iOS9

ollio
la source
3
Cela fonctionne, mais mettre la position: fixé à votre corps vous fait défiler vers le haut
ThaoD5
1
Bizarre mais cela a fonctionné pour moi sans position fixe, aussi. Un seul parmi toutes les solutions ici!
Garavani le
Un seul qui a fonctionné pour moi, utilisant chrom et boostrap + angularJS
kiwicomb123
6

Gardez la fenêtre intacte: <meta name="viewport" content="width=device-width, initial-scale=1.0">

En supposant que vous souhaitiez obtenir l'effet d'une barre noire continue sur le côté droit: #menubarne doit pas dépasser 100% , ajustez le rayon de la bordure de sorte que le côté droit soit carré et ajustez le rembourrage pour qu'il s'étende un peu plus vers la droite . Modifiez ce qui suit dans votre #menubar:

border-radius: 30px 0px 0px 30px;
width: 100%; /*setting to 100% would leave a little space to the right */
padding: 0px 0px 0px 10px; /*fills the little gap*/

Ajuster le paddingà 10px laisse bien sûr le menu de gauche au bord de la barre, vous pouvez mettre les 40px restants à chacun des li, 20px de chaque côté gauche et droit:

.menuitem {
display: block;
padding: 0px 20px;
}

Lorsque vous redimensionnez le navigateur plus petit, vous trouverez toujours l'arrière-plan blanc: placez votre texture d'arrière-plan à la place de votre div vers body. Ou bien, ajustez la largeur du menu de navigation de 100% à une valeur inférieure à l'aide de requêtes multimédias. Il y a beaucoup d'ajustements à apporter à votre code pour créer une mise en page appropriée, je ne suis pas sûr de ce que vous avez l'intention de faire, mais le code ci-dessus corrigera en quelque sorte votre barre qui déborde.

Anne
la source
si vous utilisez, box-sizing: border-box;vous pouvez ajouter un remplissage à un div de largeur 100%.
Charles John Thompson III
6

La création d'un div wrapper de site à l'intérieur du corps et l'application du overflow-> x: hidden au wrapper INSTEAD du body ou html a résolu le problème.

Cela a fonctionné pour moi après avoir également ajouté position: relativeà l'emballage.

Isaac F
la source
Cela a fonctionné pour moi. L'effet secondaire est que j'ai deux barres de défilement au lieu d'une. La solution était de le faire à la overflow: hiddenplace overflow-x: hidden. Fonctionne sur mobile Safari, Chrome, IE11 sur OSX et Win.
pop le
4

L'ajout d'un wrapper <div>autour de l'intégralité de votre contenu fonctionnera en effet. Bien que sémantiquement "icky", j'ai ajouté un div avec une classe de overflowWrap juste à l'intérieur de la bodybalise, puis j'ai défini mon CSS comme ceci:

html, body, .overflowWrap {
overflow-x: hidden;
}

Peut-être exagéré maintenant, mais fonctionne comme un charme!

MBurnette
la source
4

J'ai rencontré le même problème avec les appareils Android mais pas les appareils iOS. Géré pour résoudre en spécifiant la position: relative dans la div externe des éléments absolument positionnés (avec débordement: masqué pour la div externe)

Kwok Pan Fung
la source
4

Aucune solution unique précédente ne fonctionnait pour moi, j'ai dû les mélanger et j'ai également résolu le problème sur les appareils plus anciens (iphone 3).

Tout d'abord, j'ai dû envelopper le contenu html dans un div externe:

<html>
  <body>
    <div id="wrapper">... old html goes here ...</div>
  </body>
</html>

Ensuite, j'ai dû appliquer le débordement caché au wrapper, car overflow-x ne fonctionnait pas:

  #wrapper {
    overflow: hidden;
  }

et cela a résolu le problème.

spaghetticode
la source
En quoi est-ce différent de la réponse de @ Indigenuity?
Ian Kemp
3
@ian Kemp overflow: hidden! = overflow-x: hidden
spaghetticode
3

J'ai résolu le problème en utilisant overflow-x: hidden; comme suit

@media screen and (max-width: 441px){

#end_screen { (NOte:-the end_screen is the wrapper div for all other div's inside it.)
  overflow-x: hidden;
   }
 }

la structure est la suivante

1st div end_screen >> inside it >> end_screen_2(div) >> inside it >> end_screen_2.

'end_screen is the wrapper of end_screen_1 and end_screen_2 div's

vikas etagi
la source
3

Comme l'a dit subarachnid, overflow-x hidden pour le corps et le html a fonctionné Voici un exemple de travail

**HTML**
<div class="contener">
  <div class="menu">
  das
  </div>
  <div class="hover">
    <div class="img1">
    First Strip
    </div>
     <div class="img2">
    Second Strip
    </div>
</div>
</div>
<div class="baner">
dsa
</div>

**CSS**
body, html{
  overflow-x:hidden;
}
body{
  margin:0;
}
.contener{
  width:100vw;
}
.baner{
   background-image: url("http://p3cdn4static.sharpschool.com/UserFiles/Servers/Server_3500628/Image/abstract-art-mother-earth-1.jpg");
   width:100vw;
   height:400px;
   margin-left:0;
   left:0;
}
.contener{
  height:100px;
}
.menu{
  display:flex;
  background-color:teal;
  height:100%;
  justify-content:flex-end;
  align:content:bottom;
}
.img1{
  width:150px;
  height:25px;
  transform:rotate(45deg);
  background-color:red;
  position:absolute;
  top:40px;
  right:-50px;
  line-height:25px;
  padding:0 20px;
  cursor:pointer;
  color:white;
  text-align:center;
  transition:all 0.4s;
}
.img2{
  width:190px;
  text-align:center;
  transform:rotate(45deg);
  background-color:#333;
  position:absolute;
  height:25px;
  line-height:25px;
  top:55px;
  right:-50px;
  padding:0 20px;
  cursor:pointer;
  color:white;
  transition:all 0.4s;
}
.hover{
  overflow:hidden;
}
.hover:hover .img1{
  background-color:#333;
  transition:all 0.4s;
}
.hover:hover .img2{
  background-color:blue;
  transition:all 0.4s;
}

Lien

Skylin R
la source
1

Je travaille juste dessus depuis quelques heures, essayant diverses combinaisons de choses de cette page et d'autres. La chose qui a fonctionné pour moi à la fin était de créer un div wrapper de site, comme suggéré dans la réponse acceptée, mais de définir les deux débordements sur masqués au lieu de simplement le débordement x. Si je laisse overflow-y au scroll, je me retrouve avec une page qui ne défile que verticalement de quelques pixels, puis s'arrête.

#all-wrapper {
  overflow: hidden;
}

Cela suffisait, sans rien définir sur le corps ou les éléments html.

highfellow
la source
1

J'avais essayé de nombreuses façons à partir des réponses dans ce sujet, cela fonctionne principalement mais j'ai eu des effets secondaires, comme si j'utilisais overflow-x, body,htmlcela pourrait ralentir / geler la page lorsque les utilisateurs font défiler vers le bas sur un mobile.

utiliser position: fixedsur wrapper / div à l'intérieur du corps est bien aussi, mais quand j'ai un menu et que j'utilise Javascript, cliquez sur le défilement animé jusqu'à une section, cela ne fonctionne pas.

J'ai donc décidé d'utiliser touch-action: pan-y pinch-zoomsur wrapper / div à l'intérieur du corps. Problème résolu.

Jirayu L
la source
0

La seule façon de résoudre ce problème pour mon modal bootstrap (contenant un formulaire) était d'ajouter le code suivant à mon CSS:

.modal {
    -webkit-overflow-scrolling: auto!important;
}
Tobias
la source