web-dev-qa-db-fra.com

Propriété CSS3 webkit-overflow-scrolling: touch ERROR

iOS 5 a proposé aux concepteurs Web une nouvelle propriété -webkit-overflow-scrolling:touch qui utilise l'accélérateur matériel de périphériques iOS pour permettre le défilement natif d'un div à défilement.

Une fois implémenté sur notre site en développement, cela fonctionne mais pas bien. Je crois qu’il peut y avoir un problème de CSS et je pose donc la question ici.

Le suivant fiddle vous montrera que cela fonctionne parfaitement 

Si vous visitez notre site en développement, vous trouverez le même panneau sous l'onglet Installations mais sur iOS, bien que le défilement soit parfait, la section débordée ne s'affiche pas avec des images littéralement coupées en deux.

http://www.golfbrowser.com/courses/mill-ride/

Je ne sais pas comment résoudre ce problème http://www.golfbrowser.com/photo.PNG

57
Robin Knight

Comme @relluf l'a souligné, l'application de transitions 3D sur l'élément relatif corrige le bogue. Cependant, j’ai étudié la question un peu plus loin et il semble que l’application de -webkit-transform: translateZ(0px) fonctionne également (c’est ce que Google fait dans le conteneur de cartes gmaps) et il n’est pas nécessaire que ce soit sur l’élément positionné, mais uniquement le descendant direct de l’élément scrollable.

Donc, si vous ne voulez pas garder manuellement une liste de tous les endroits où le correctif est nécessaire, vous pouvez le faire:

element {
    -webkit-overflow-scrolling: touch;
}

element > * {
    -webkit-transform: translateZ(0px);
}
85
spheroid

Quel idiot ils ont lâché ici. J'ai essayé toutes sortes de solutions de contournement jusqu'à ce que j'ai finalement trouvé la seule propriété nécessaire pour que les éléments soient correctement restitués dans un -webkit-overflow-scrolling:touch div: position: static 

Les éléments à positionnement relatif et absolu sont toujours coupés à la frontière et sont complètement absents (à l'exception de l'espace vide) à l'extérieur de celle-ci. Si vous modifiez la propriété position dynamiquement, de statique à absolu, seule la partie visible de la fenêtre d'affichage défilante reste restituée, quel que soit le décalage.

16
user1012566

J'ai rencontré ce bug aussi. Je l'ai corrigé en appliquant les fichiers CSS suivants aux éléments parents:

-webkit-transform: translate3d(0, 0, 0);

Cependant, j'ai remarqué que cela ralentissait le rendu et pouvait sélectionner d'autres éléments d'entrée que ceux souhaités lorsqu'un élément d'entrée touché était déplacé au centre de la vue (par Safari/iOS).

7
relluf

Dans iOS, lorsqu'un élément dans un élément avec -webkit-overflow-scrolling: touch set est positionné de manière absolue (ou fixed) par rapport à un élément situé en dehors du conteneur de défilement, l'élément n'est rendu qu'une seule fois et le rendu n'est pas mis à jour lorsque l'élément est défilé. Exemple HTML:

<div class="relative-to-me">
  <div class="scrollable">
    <div class="absolutely-positioned">
    </div>
  </div>
</div>

Si vous forcez un re-rendu en modifiant une propriété CSS (dans l'inspecteur, par exemple), vous pouvez voir que le positionnement de l'élément est restitué à l'emplacement correct. Je soupçonne que cela résulte de certaines fonctionnalités de performance destinées à optimiser les performances de défilement.

La solution à ce problème consiste à définir will-change: transform sur l'élément positionné de manière absolue (ou fixe).

.absolutely-positioned {
    will-change: transform;
}
2
joeyhoer

J'ai étudié ce bogue en profondeur, j'ai également créé un jsfiddle et l'ai soumis à Apple dans un rapport de bogue. Veuillez consulter: iOS5 Les images disparaissent lors du défilement avec webkit-overflow-scrolling: touch Dès que Apple me répondra, je vous le signalerai afin que vous puissiez rester au courant de ce sujet bug très ennuyeux

2
lucaferrario

J'ai également rencontré le problème suivant: le débordement de défilement avec le jeu -webkit-overlfow-scrolling au toucher entraînait le redessinage des problèmes liés au positionnement d'éléments. Dans mon cas, j'avais une liste où les éléments individuels avaient un positionnement relatif afin que je puisse utiliser le positionnement sur leurs éléments enfants. Avec le CSS ci-dessus sur iOS 5, lorsque l'utilisateur faisait défiler le contenu masqué, un délai passait avant qu'il ne redessine l'écran pour passer en revue les éléments. C'était vraiment énervant. Heureusement, j'ai découvert que, si je donnais également une position relative au nœud parent, le problème était résolu.

1
Robert

J'ai essayé différentes solutions, mais cela ne semblait pas fonctionner parfaitement dans mon cas. 

Enfin, jQuery fonctionne bien: 

Appliquez la propriété -webkit-overflow-scrolling à chaque fois que vous effectuez des retouches.

* Au début, j'ai également appliqué -webkit-overflow-scrolling: auto when TouchDown , pour désactiver le rendu iOS. Mais cela fit clignoter la page. Alors je l'ai laissé tomber, puis fonctionne bien étonnamment!

Vérifiez les lignes ci-dessous, espérons que cela aide:

<!-- ???? JQuery Functions-->

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">

//???? Apply -webkit-overflow-scrolling in Every TouchEnd
$(document).on('click touchend', function(event) {
    $("#TestDIV").css({"-webkit-overflow-scrolling":"touch"});
});

</script>



<!-- ???? html Elements & Style -->

<div id="TestDIV">
    <div class="Element"></div>
    <div class="Element"></div>
    <div class="Element"></div>
    <div class="Element"></div>
    <div class="Element"></div>
</div>

<style>
#TestDIV{
    white-space: nowrap;
    overflow-x: scroll;
    -webkit-overflow-scrolling:touch;
}

#TestDIV .Element{
    width:300px;
    height:300px;

    margin: 2px;

    background-color: gray;

    display: inline-block;
}
#TestDIV .Element:nth-child(odd){
    background-color: whitesmoke;
}   
</style>
0
Corxit Sun

Le bogue persiste dans iOS 6. Si votre problème est lié à position: relative, vous pouvez le résoudre en définissant z-index: 1 temporairement via JS. -webkit-transform: translate(...) ne fonctionnait pas avec position: relative dans mon cas.

0
Bernd