14 votes

Overflow:hidden sur body est cassé dans ios6

J'ai fait quelques tests et d'après ce que je peux voir, il y a un bug dans Safari mobile sur iOS 6.

Lorsqu'on ajoute overflow:hidden à la balise body et que l'on déplace un élément en dehors du corps en utilisant transform:translateX(100%); cela crée un espace scrollable supplémentaire pour cet élément. Sur tous les navigateurs de bureau, il est "caché".

Voici une démo: http://jsfiddle.net/mUB5d/1 . Ouvrez cela dans Safari mobile et vous verrez ce qui ne va pas.

Est-ce que quelqu'un pourrait jeter un œil sur Safari 6 sur Mac OS pour voir si le bug est également présent là-bas? Est-ce que quelqu'un connaît un contournement autre que de créer un autre parent autour de mon élément?

Merci pour vos retours!

9voto

Joel Glovier Points 1842

Non. Safari 6 sur Mac ne présente pas le bug. Les barres de défilement ne sont pas présentes.

Je l'ai exécuté sur OSX Mountain Lion (10.8.2)

entrer la description de l'image ici

Pour répondre plus en détail à votre question, la raison de ce problème est probablement liée au rendu de zoom de Safari Mobile plutôt qu'à un bug de débordement masqué. L'élément est en fait caché hors de l'écran (remarquez ci-dessous que j'ai fait défiler vers la droite tout le chemin, il ne me montre toujours pas l'élément de largeur 100% complet - 90% de celui-ci est en fait masqué.

Il y a probablement quelque chose à voir avec les iframes et le zoom de la page. Cela ressemble toujours à un bug cependant.

Je suppose que vous faites une démonstration dans JSFiddle à partir d'un exemple réel. Si vous retournez à votre exemple réel (en dehors du territoire des iframes), essayez d'ajouter cette balise meta à l'en-tête si vous ne l'avez pas déjà, et voyez si cela aide:

entrer la description de l'image ici

9voto

hashchange Points 979

Ceci est un comportement normal sur iOS (et uniquement sur iOS). Vous pouvez contourner cela en déclarant overflow: hidden à la fois sur les éléments html et body. De plus, vous devez définir le corps sur position: relative.

Comportement de débordement

Plusieurs choses entrent en jeu ici. Pour comprendre pourquoi la correction fonctionne, nous devons d'abord examiner comment le débordement du viewport est défini.

  • Le débordement du viewport est déterminé par le paramètre de débordement de l'élément html.
  • Mais tant que vous laissez le débordement de l'élément html à sa valeur par défaut (visible), le paramètre de débordement du corps est également appliqué au viewport. C'est-à-dire, vous pouvez définir soit html soit body sur overflow: hidden lorsque vous ciblez le viewport. Le comportement de débordement de l'élément body lui-même n'est pas affecté - jusqu'à présent.
  • Maintenant, si vous définissez le débordement de l'élément html sur autre chose que visible, le transfert de body au viewport ne se produit plus. Dans votre cas particulier, si vous définissez les deux débordements sur hidden, le paramètre de l'élément html est appliqué au viewport, et l'élément body masque également son débordement.

C'est en fait le cas dans tous les navigateurs raisonnablement modernes, et non spécifique à iOS.

Particularités d'iOS

Maintenant, iOS ignore overflow: hidden sur le viewport. Le navigateur se réserve le droit d'afficher le contenu dans son ensemble, peu importe ce que vous déclarez dans le CSS. C'est intentionnel et ce n'est pas un bug, et cela reste le cas dans iOS 7 et 8. Personne ne peut rien y faire non plus - cela ne peut pas être désactivé.

Mais vous pouvez contourner cela en faisant en sorte que l'élément body lui-même, pas le viewport, cache son débordement. Pour y parvenir, vous devez d'abord définir le débordement de l'élément html sur autre chose que visible, par exemple sur auto ou hidden (dans iOS, il n'y a pas de différence entre les deux). De cette manière, le paramétrage de débordement du corps n'est pas transféré au viewport et reste effectivement sur l'élément body lorsque vous le définissez sur overflow: hidden.

Avec cela en place, la plupart du contenu est masqué. Mais il y a toujours une exception: les éléments positionnés absolument. Leur parent de décalage ultime est le viewport, pas le corps. S'ils sont positionnés quelque part hors écran, à droite ou en bas, vous pouvez toujours défiler jusqu'à eux. Pour vous prémunir contre cela, vous pouvez simplement définir l'élément body sur position: relative, ce qui en fait le parent de décalage du contenu positionné et empêche ces éléments de sortir du cadre body.

Réponse en code

Il y a une dernière chose à surveiller: le corps lui-même ne doit pas être plus grand que le viewport.

Donc le corps doit être défini à 100% de la largeur et de la hauteur du viewport. (Le mérite d'une manière de le réaliser en CSS uniquement revient à cette réponse SO.) Les marges sur les éléments html et body doivent être de 0, et le html ne doit pas avoir de rembourrage ou de bordure non plus.

Enfin, pour traiter le rembourrage du corps, et au cas où vous voudriez un bord sur le corps, faites en sorte que les calculs fonctionnent avec box-sizing: border-box pour le corps.

Voici donc.

html {
  overflow: hidden;

  height: 100%;
  margin: 0;
  padding: 0;
  border: none;
}

body {
  overflow: hidden;
  position: relative;

  box-sizing: border-box;
  margin: 0;
  height: 100%;
}

NB Vous pouvez définir le rembourrage et la bordure du corps comme bon vous semble.

1voto

RobW Points 2202

Après avoir lutté avec cela pendant un certain temps, j'ai découvert que les balises html et body ont besoin d'un débordement caché pour masquer réellement le contenu qui déborde. Sur les éléments à l'intérieur de la balise body, le débordement caché fonctionne bien, donc notre choix est une règle CSS supplémentaire ou un élément d'enveloppe.

0voto

SANTOSH YADAV Points 1

Pour moi ça fonctionne

J'ai implémenté dans le menu latéral gauche

if($('.left-menu-panel').is(':visible')) {$("body").addClass('left-menu-open');$("html").css('overflow-y','hidden'); $('body').click(function() {$("body").removeClass("left-menu-open") ;$("html").css('overflow-y','visible'); });$('#off-canvas-left').click(function(event){event.stopPropagation();}); }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X