- This topic is empty.
January 16, 2017 at 10:05 am #250068
So this one has been bugging me for quite a while.
I have this plugin that makes elements sticky as soon as you scroll a certain amount of pixels. Here is a very reduced demo:
(Full code: https://jsbin.com/nuzukujupe/edit?html,css,js,output )
If you check it on a desktop computer, you’ll see that it works as intended: on scroll, it checks how much the user has scrolled. If it’s more than 200 pixels, the element becomes sticky (by giving it position:fixed). If not, it becomes normal again.
Now here’s the kicker. On touch screens, the element only becomes actually sticky after scrolling is fully finished. Check what I mean:
- load page
- scroll sllllooooowwwllllyyyyy until you hit 200 or a little more, keep your finger on the screen!
- the status (in the top left box) will change and the element will disappear
- let go of the screen
- only NOW the element appears again, sticky and all
- load page
- scroll FAST (quick swipe up)
- the status (in the top left box) will change and the element will disappear off screen
- once scrolling is done, the element will appear again, sticky
So, since the status (in the RED box) updates immediately after you hit 200, this event is captured properly and at the right time.
The problem is the visual change from position:static to position:fixed for the sticky element; it looks like there is some “in-between” status where it’s just invisible until the scrolling is fully finished.
I really need the element to be sticky (and visible) right the same moment when the red box status says “YES” and I can’t seem to figure a good (or working) solution.
I did come across this page but I don’t see any useful fix to be honest. Or I just don’t understand it: https://remysharp.com/2012/05/24/issues-with-position-fixed-scrolling-on-iosJanuary 16, 2017 at 11:35 am #250077
One workaround seems to be adding a wrapping div inside the sticky one with “transform: translate3d(0%,0,0);”, see https://output.jsbin.com/voxocewehu
Any ideas how clean or dirty this method is?January 16, 2017 at 1:51 pm #250082
I think it’s a commonly accepted way to give an element it’s own stacking context…
Although I cannot explain why it makes the element respond to the scroll event sooner. I was convinced that it wouldn’t fire at all until the panning is released.
Before iOS 8, Apple’s mobile browser did not continuously fire scroll events
So I would imagine it only works for those later versions. It also seems they were late to the party (and I to get informed) with that:
It’s not just the mobile iOS browser that acts odd with nested fixed elements by the way. I just rewrote an old page where several fixed elements would disappear on Chrome and Opera desktop when scrolling. Fixed that by making them direct children of
body.January 16, 2017 at 4:17 pm #250085
I just rewrote an old page where several fixed elements would disappear on Chrome and Opera desktop when scrolling. Fixed that by making them direct children of body.
By doing it like that, wouldn’t you lose your styles (since it’s losing parents)?January 16, 2017 at 4:43 pm #250086
Good point, that would not be very convenient with existing structures. But that page was so old (my first efforts at fiddling around with web design) that it deserved a complete rewrite. The fixed elements there are just a “frame” for housing the other content and not markup that would need nesting, so I removed that. But if anything, it does illustrate a similar issue.
I think the webkit related browsers have a long history of problematic fixed positioning, there’s quite a few more bugs around. Firefox seems to have taken the approach from the beginning to render fixed layers separately, repainting them most smoothly. And IE’s somewhere in between, I think.January 16, 2017 at 5:20 pm #250087
Side note, I think you also must have concluded there are two separate characteristics going on… one is the rendering of fixed positioned elements on Webkit browsers which makes them behave as children first when it comes to repaints (unless given their own layer). The other is the fact that older mobile browser versions don’t update the scroll position when panning (Remy Sharp’s link), for which there would only be a JS workaround – keeping track of finger movement with touch events and updating positioning on the basis of that. Relevant for Android 3.0 (before that it’s hardly doable) and iOS7-.
It’s mostly theory on my side in any case, going on you saying that the fixed worked as described. I can’t actually test anything (yet) on iOS.