CSS3 property webkit-overflow-scrolling:touch ERROR
Asked Answered
T

8

62

iOS 5 released web designers a new property -webkit-overflow-scrolling:touch that uses the iOS devices hardware accelerator to provide native scrolling for a scrollable div.

When implemented on our site in development it does work but not well. I believe there may be a CSS issue hence I ask here.

The following fiddle will show you it working perfectly

If you pop over to our site in development you will find the same panel under facilities tab but on iOS although the scrolling is perfect the overflowed section is not shown with pictures literarily chopped in two.

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

I have no idea how to fix this http://www.golfbrowser.com/photo.PNG

Trumantrumann answered 18/10, 2011 at 13:37 Comment(1)
I've encountered a similar issue on iOS6 (the page in question worked fine on iOS5). Fixed by applying -webkit-transform: translate3d(0, 0, 0); to the img tags which had been chopped off, working fine now.Inflationary
M
94

As @relluf pointed out, applying 3D transitions on the relative element fixes the bug. However, I investigated it a bit further and it seems that applying -webkit-transform: translateZ(0px) works too (this is what Google does on gmaps map container) and it does not need to be on the relatively positioned element, just the direct descendant of the scrollable element.

So if you don't want to manually keep a list of all the places where the fix is needed, you just might do:

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

element > * {
    -webkit-transform: translateZ(0px);
}
Mukul answered 12/4, 2012 at 11:32 Comment(10)
Also for me. The secret is to do the -webkit-transform on the items INSIDE the scrolling area.Unquestionable
I feel like element > * was buggy. Although it fixed the clipping problem, the scrolling element would flicker while scrolling. I fixed the flickering by applying the hardware acceleration to all elements with: element * (no direct child selector).Negativism
this kinda reminds me of the old days of having to put zoom:1 on elements to fix hasLayout issues. :(Lists
This helped me a lot.. But 1 question i have. I am also scrolling bg image like a parallax scroll effect, i.e. jerky? any help?Okelley
are you saying we're repeating history @Lists ?! certaintly not... ;) ... something also worth mentioning is GreenSock.com's GSAP animation tool. The address problems like these along w/ some css3 problems that we thought would fix everything (sike). Check it outAscribe
I posted this comment on another thread, but use this solution with care on mobile devices. I saw out of memory errors when trying this blindly (an extra 70 MB of memory usage for a few dozen elements). Instead, I resorted to using this solution but disabling the transform after one second.Primal
this is not a good solution at all, as it will create a lot more rendering layers to the browser and will make much more layer composition work on the GPU! Mobile devices have lower GPU memory and will not support this well. See aerotwist.com/blog/on-translate3d-and-layer-creation-hacksLuann
This solution is seriously terrible. An incredibly inefficient selector that will spawn tons of GPU rendering layers.Sunnisunnite
I'm getting the flickering effect also. The element stays in place, but jiggles around when you scroll. How to fix this?Berlioz
Another problem is that if you have any elements with position:fixed inside a transform, it makes them relative to that transformed element, instead of the viewport. So it's not necessarily safe to do this. Still looking for a better solution.Hirsch
S
18

What a bugger they let loose here. Tried all manner of workarounds until I finally found the only property needed by for elements to be properly rendered in a -webkit-overflow-scrolling:touch div: position: static

Relative and absolute positioned elements are always cut off on the boundary, and completely missing (except for empty space) outside of it. If you change the position property dynamically, from static to absolute, only the visible portion of the scrollable div viewport stays rendered, wherever the offset happens to be.

Sinusitis answered 25/10, 2011 at 23:4 Comment(1)
This worked for me, I removed position: relative from some input elements (leaving them as the default position :static) and they render properly throughout the scroll.Claver
P
6

I have run into this bug as well. I fixed it by applying the following css to parent elements:

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

However, I have noticed that that slows down rendering and might select other input elements than wanted when a touched input element is scrolled into the center of the view (by Safari/iOS).

Parterre answered 4/1, 2012 at 20:43 Comment(2)
This worked for me, setting it on the position: relative element inside the -webkit-overflow-scrolling: touch container.Wallah
Please ignore the part "and might select other input elements than wanted when a touched input element is scrolled into the center of the view". I was mistaken.Parterre
A
3

In iOS, when an element inside an element with -webkit-overflow-scrolling: touch set is positioned absolutely (or fixed) relative to an element outside of the scrolling container, the element is rendered only once and the rendering is not updated as the element is scrolled. Sample HTML:

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

If you force a re-render by changing a CSS property (in the inspector for example), you can see that the element's positioning is re-rendered into the correct location. I suspect this is a result of some performance features to optimize scrolling performance.

The solution to this problem is to set will-change: transform on the absolutely (or fixed) positioned element.

.absolutely-positioned {
    will-change: transform;
}
Armalda answered 13/5, 2017 at 16:21 Comment(1)
This seems odd to me b/c ur never changing the transform property, or are we?Attendant
R
2

I deeply investigated this bug, I also created a jsfiddle and submitted it to Apple in a bug report. Please see: iOS5 Images disappear when scrolling with webkit-overflow-scrolling: touch As soon as Apple replies to me, I'll report it on that topic so you can stay up-to-date about this very annoying bug

Remorseful answered 26/11, 2011 at 15:37 Comment(0)
H
1

I also experienced the problem where overflow scroll with -webkit-overlfow-scrolling set to touch resulted in redraw problems with positioned elements. In my case I had a list where the individual items had relative positioning so that I could use positioning on their child elements. With the above CSS on iOS 5, when the user scrolled hidden content into view, there was a momentary delay before it redrew the screen to review the elements. It was really annoying. Fortunately I discover that if I gave the parent node position relative as well, this was resolved.

Hudak answered 5/12, 2011 at 20:57 Comment(0)
D
1

The bug still lives in iOS 6. If your issue is related to position: relative, you might solve the issue be setting z-index: 1 temporarily via JS. -webkit-transform: translate(...) did not work with position: relative in my case.

Degrading answered 15/3, 2013 at 21:10 Comment(0)
S
0

I tried some different solutions, seemed not work perfectly in my case.

Finally I've found a way works fine with jQuery:

Apply -webkit-overflow-scrolling property every time when you touch up.

*At first I Applied Also -webkit-overflow-scrolling:auto when TouchDown, to disable iOS rendering. But it made Page blink. So I dropped it away, then works fine surprisingly!

Check lines below, hope it helps:

<!-- 🍉 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>
Signorina answered 22/11, 2017 at 9:19 Comment(1)
This helps in my case (text disappearing when typing in a text box) as it causes re-render due to css changes in React setup. However, I had to set it to auto first, then touch. Found out this issue is fixed in iOS 13.Shielashield

© 2022 - 2024 — McMap. All rights reserved.