Css bogue scroll-snap iOS 10

J’ai remarqué un bug étrange dans iOS 10 avec les propriétés CSS scroll-snap .

Voici mon css:

#springBoard{ height: 100%; width: 100%; font-size: 0px; white-space: nowrap; overflow: scroll; -webkit-overflow-scrolling: touch; -webkit-scroll-snap-type: mandatory; -webkit-scroll-snap-points-x: repeat(100%); } section{ display: inline-block; width: 100%; height: 100%; vertical-align: top; font-size: 16px; } 

Si je fais défiler par programme jusqu’à un point d’accrochage et que vous modifiez ensuite le contenu dans le conteneur de capture instantanée, le navigateur revient au premier point d’accrochage.

 // Programatically scroll the scroll-snap container $("#springBoard")[0].scrollLeft = 320 

Cela ne semble pas être lié à la façon dont je déclenche le défilement. Toutes ces méthodes de défilement produisent le même résultat:

 $("#springBoard")[0].scrollLeft = 320 $("#springBoard").animate({scrollLeft: 320}, 1) $("#springBoard > section:eq(1)")[0].scrollIntoView() window.location.hash = "sectionId" 
  1. Le bogue ne se produit pas lorsque vous faites défiler manuellement (voir le commentaire de @ maxime ci-dessous).
  2. Il est présent depuis la version 10.3.2 d’iOS.
  3. Je ne sais pas si c’est corrigé dans iOS 11.

J’ai passé quelques jours à essayer de résoudre le problème mais sans succès jusqu’à présent.

Voici un exemple simplifié de mon nav:

Démo de codepen

Est-ce que quelqu’un sait comment contourner ce stupide bug?

J’ai créé mon propre scroll-snap HORIZONTAL jquery qui se déclenche lors du chargement de la page , du redimensionnement de la fenêtre et du défilement du conteneur – cela évite d’avoir à utiliser css:

 $(".container").scroll(function() { 

L’instruction if / else suivante permet de modifier la largeur de l’object en fonction de la largeur de la page. Sinon, vous pouvez simplement le supprimer et définir var width = votre largeur par défaut

  var width = 1; //100% - default value / small screen if(window.innerWidth >= 993) //large screen width = 1/4; //25% else if(window.innerWidth >= 601) //medium screen width = 1/3; //33.333% var containerWidth = $(".container").width(); var sectionWidth = containerWidth * width; //gets the length of each section var currentScroll = $(".container").scrollLeft(); var farOff = currentScroll % sectionWidth; //determines how far user is from the beginning of the current section if(farOff == 0) //just for efficiency return; clearTimeout($.data(this, 'scrollTimer')); $.data(this, 'scrollTimer', setTimeout(function() { if(farOff >= sectionWidth/2) //scroll-snaps to next section $(".container").animate({ scrollLeft: (currentScroll + sectionWidth - farOff), }); else //scroll-snaps to previous section $(".container").animate({ scrollLeft: (currentScroll - farOff), }); }, 550)); }); 

Vous trouverez ci-dessous le CSS qui accompagne mon exemple de bouton de défilement.

 div.container{ overflow-x: scroll; -webkit-overflow-scrolling: touch; -o-overflow-scrolling: scroll; -moz-overflow-scrolling: scroll; overflow-y: hidden; white-space: nowrap !important; } .container section{ display: inline-block; padding: 10px; width:100%; vertical-align: top; margin-bottom: 10px; } .container > section > div{ overflow: initial; white-space: normal; } @media (min-width: 601px){ /* medium */ .container section{ width: 33.33333333%; } } @media (min-width: 952px){ /* large */ .container section{ width: 25%; } } 

S’il vous plaît essayez comme ceci:

 $('#springBoard').animate({scrollLeft: $('#springBoard').position().left + 320},1 );