Consider the following scenario:
You have 2 scrollable elements.
- A long flowing list of items attached to $(document).scroll()
- A separate container/overlay that listens to $(".class").scroll()
With the following CSS properties.
body {
overflow-y: scroll;
height: 100%;
}
.class {
height: 100%; /* 50% 20% 200px whatever you may */
position: fixed;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
In other words, a very standard setup, that in 2017 should work without any issues on any device. Wrong.
Here are the problems that I've experienced with this simple setup through the years, and never found a good, reliable solution to:
- The overlay starts flickering from mild to extreme when scrolled to top or bottom of overlay when 100% height, no matter HTML complexity across all iDevices. (Because of z-index issue with over-scrolling, or hardware acceleration issue, I don't know).
- The scrolling completely stops for the overlay when at the top or bottom in order to wait for body-scroll to stop over-scrolling.
When the scrolling has wrongfully stopped for the container (whilist over-scrolling kicks in), and the user keeps scrolling, the body will scroll instead, resulting in very inconsistent user experience as the user will now end up somewhere else in the body-scroll than they were before opening the overlay. It's also annoying to have to stop scrolling in order to wait for over-scrolling to stop.
if container is 100% height, and without scroll – If user starts scrolling, the body will scroll and scrollbar will be visible, but the page seemingly isn't scrolling, resulting in inconsistent user experience.
Some of the solutions I've tried without any success.
- iScroll. iScroll stops the over-scrolling issue by preventing any touch events on document. But delivers inconsistent and bad scrolling experience imho. Besides it shouldn't even be needed anymore.
- Every other scrolling plugin imaginable.
- Event delegation – Trying to enable scroll for only the element that is being interacted with. Works on desktop. Not mobile safari.
- Every jQuery scrolling aid imaginable. Mild success but very inconsistent.
It seems that whatever fix has been presented in the past, has somehow been depreciated for "various reason" (Don't mean to sound conspiratorial.)
I read a few weeks back that Apple is working on an update for the scrolling for webkit to make it more homogenous across all types of content-types served on the iPhone. But until then, this simple setup remains very problematic on mobile Safari.
I may have come up with a solution to this finally. But I'm very curious to hear how others are solving this issue in 2017...
Update 2018 for WebView Apps While Apple is making no efforts in solving this matter, the absolute best solution to completely eradicate any problems if you're building webview apps is to entirely disable browser-scroll (webview) completely directly in Swift.
When your WebView has loaded simply use:
override func viewDidLoad() {
super.viewDidLoad()
wkWebView1.scrollView.isScrollEnabled = false
wkWebView1.scrollView.bounces = false
}
And then in your CSS set the scrolling individually for each container that needs to be scrollable.
Note that $(document).scroll() will be completely disabled with this solution.
I hope it helps someone.