57

I'm working on a web app that uses -webkit-overflow-scrolling:touch in several places to give the overflown divs inertia scrolling.

Since updating to IOS8, -webkit-overflow-scrolling: touch stops you being able to scroll whatsoever, and the only way I have been able to fix this so far is by removing -webkit-overflow-scrolling: touch which leaves the standard sticky scrolling. Please help!

Here is an example of one of the standard classes that works in iOS5, 6, and 7:

.dashboardScroll {
    height: 100%;
    overflow-x: hidden;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch; /*MAKES OVERFLOWN OBJECTS HAVE INERTIA SCROLLING*/
    -webkit-transform: translateZ(0px); /*HELPS THE ABOVE WORK IN IOS5*/
} 
Linus Juhlin
  • 1,175
  • 10
  • 31
Jamie Beech
  • 913
  • 1
  • 9
  • 8
  • The same bug exists in iOS5 (final update for iPad1) too. – robocat Oct 15 '14 at 22:45
  • Also I had some very strange bugs with touch scrolling on Android AOSP that were fixed by using both position:relative; and overflow:hidden; on the content (or the scrollable div?!). Bugs were scrolling at 2x finger movement, not scrolling, jittery headers, and occlusion of scroll tracker. – robocat Oct 15 '14 at 22:51
  • It's definitely not the same as the iOS5 bug, because if you look at my code I have fixed that. I think it has something to do with iOS8 now recognising scroll events which is awesome for websites using parallax, but breaks the overflow scrolling. – Jamie Beech Oct 17 '14 at 06:13
  • That exact same CSS works for me. – Ade Oct 28 '14 at 08:59
  • Is that on an iOS 8 iPad? – Jamie Beech Oct 28 '14 at 09:51
  • Please make a live demo on http://jsbin.com. – Frank Conijn - Support Ukraine Nov 03 '14 at 23:03
  • I have made a demo here http://jsfiddle.net/ddpg6foy/. – Jamie Beech Nov 05 '14 at 08:48
  • It is working on here so I am thinking it may have something to do with the web app being built in iFrames? – Jamie Beech Nov 05 '14 at 08:49
  • It's weird, because it was working perfectly in all the previous iOS's and if I remove the overflow-scrolling you can scroll within the divs, it's just that horrible sticky scrolling. – Jamie Beech Nov 05 '14 at 08:53
  • @JamieBeech jsfiddle.net always puts your solution into an iframe (even if full screen link used) which means jsfiddle is definitely not usable if you are testing anything to do with scrolling/zoom/viewport/sizing/window-events/some-other-things. I use jsbin.com and click the fullsize icon (or remove /edit from the URL). – robocat Nov 17 '14 at 02:41
  • Has anyone had any success preventing iPad to do the sticky scrolling instead of scrolling the desired div? – tomazahlin Nov 25 '14 at 10:43
  • Inertia scrolling is working fine in [this JSBin](http://jsbin.com/kedukohece/1/) in the iOS simulator for iOS 8.1 on iPhone 6. – Alexander O'Mara Feb 20 '15 at 04:03
  • I think my problem is the web app is build, in framesets and iFrames so the JSBin doesn't really recreate the bug. – Jamie Beech Feb 26 '15 at 16:32
  • Are those seeing this in Cordova? I only see it when I'm running a Cordova app and include the Cordova.js file. I believe this is from how Cordova creates iFrames. Still investigating... – Perry Mar 11 '15 at 18:31
  • http://patrickmuff.ch/blog/2014/10/01/how-we-fixed-the-webkit-overflow-scrolling-touch-bug-on-ios/ – Frane Poljak Mar 18 '15 at 13:37
  • This might be helpful: http://stackoverflow.com/questions/26738764/ios8-safari-webkit-overflow-scrolling-touch-issue/26743685#26743685 – Alex Mar 31 '15 at 20:58
  • Hi Alex, I have already implemented something similar but thanks for the suggestion. I was hoping for a true fix to have surfaced by now, but it's not looking likely. – Jamie Beech Apr 02 '15 at 12:02
  • Is it only me or does -webkit-overflow-scrolling: touch; seem to have become deprecated at this point? – Reality-Torrent Oct 06 '16 at 07:42

11 Answers11

29

I had a similar problem with a (quite complex) nested scrollable div which scrolled fine in iOS 5, 6 and 7, but that intermittently failed to scroll in iOS 8.1.

The solution I found was to remove all the CSS that tricks the browser into using the GPU:

-webkit-transform: translateZ(0px);
-webkit-transform: translate3d(0,0,0);
-webkit-perspective: 1000;

By doing this, the '-webkit-overflow-scrolling: touch;' can still be included and still function as normal.

It did mean sacrificing the (for me, dubious) gains to scrolling performance that the above hacks gave in earlier incarnations of iOS, but in the choice between that and inertia scrolling, the inertia scrolling was deemed more important (and we don't support iOS 5 anymore).

I cannot at this stage say why this conflict exists; it may be that it is a bad implementation of these features, but I suspect there is something a bit deeper in the CSS that is causing it. I am currently trying to create a pared down HTML/CSS/JS configuration to demonstrate it, but maybe the heavy markup structure and the large amounts of dynamic data is necessary for it to happen.

Addendum: I did, however, have to point out to our client that if even with this fix the user starts trying to scroll on a non-scrollable element she will have to wait a second after stopping before being able to scroll the scrollable element. This is native behaviour.

Louis Féat
  • 481
  • 4
  • 9
  • My temporary solution has been to remove all this, but now I am left with the standard sticky scrolling. It will do for now but it really ruins the user experience of the app, so I wouldn't say this is the fix but more of a temporary measure. – Jamie Beech Nov 21 '14 at 16:24
  • @Jamie I was able to use -webkit-overflow-scrolling: touch; after removing the other CSS. Does this not work for you? As I arrived at this through trial and error, I'm not sure what else to suggest. Certainly, this is a change in behaviour from iOS 7 to iOS 8, so who knows... maybe it will be fixed in a patch. – Louis Féat Nov 24 '14 at 14:04
  • Hey, sorry for the MASSIVELY late reply. No, this solution didn't work for me. After spending quite a lot of time trying to find a solution I kinda gave up. – Jamie Beech Feb 26 '15 at 16:34
  • 1
    hey even me also facing the same issue, this solution not able to fix, i am using ios11 – madhuiOS May 25 '18 at 11:30
9

I had this problem and found a solution. The solution is that, you have to put your content into two containers for ex:(.dashboardScroll > .dashboardScroll-inner) and give the inner container ".dashboardScroll-inner" 1px more height than the parent ".dashboardScroll" throug this css3 property

.dashboardScroll-inner { height: calc(100% + 1px);}

check out this :

http://patrickmuff.ch/blog/2014/10/01/how-we-fixed-the-webkit-overflow-scrolling-touch-bug-on-ios/

or otherwise if you can't add another container use this:

.dashboardScroll:after { height: calc(100% + 1px);}
  • 1
    Yup, that fixed it for me. LESS: .content-scrollable { .position(absolute, 0, 0, 0, 0); background: @color-empty; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; } .content-scrollable-inner { height: calc(100% + 1px); } HTML:
    >
    – Kapil Pendse Apr 23 '16 at 01:39
6

I had the same problem in a Cordova web app. For me, the problem was that I had a parent <div> that was animated and had the property animation-fill-mode: forwards;

Removing this property solved the problem and fixed the broken overflow-scrolling.

clauderic
  • 61
  • 1
  • 2
1

I was not able to solve the problem with previous answers. So after a few hours a gave the iScroll library a try, iScroll. I know including an extra library (and quite sizable) to add scrolling for just iOS is not great but this is what worked for me. Just follow the readme, the lite version suffices.

Disadvantages:

  • Scrolling on Android now looks like crap, it is not native anymore.
  • It is not possible to refresh the page by scrolling anymore
  • You need to apply another fix for Android : Clicks not working

I am unsure if I will use it, but if you are in need give it a go.

Kristjan Liiva
  • 9,069
  • 3
  • 25
  • 26
1

I tried every solutions here without success. I was able to make it work by having the property -webkit-overflow-scrolling: touch; on the scrollable div AND on the parent container.

div.container {
    -webkit-overflow-scrolling: touch;
}

div.container > div.scrollable {
    -webkit-overflow-scrolling: touch;
    overflow-y: auto;
}
Gabriel Bull
  • 344
  • 3
  • 8
1

Preventing touch events from surrounding elements bubbling up the DOM is another potential solution, you may notice that scrolling stops when surrounding DIV elements receive the touch or drag events. We had this particular issue in a menu that needed to scroll smoothly. Turning off those events helped stop the "sticking" of the scroll able element.

$html.bind('touchmove', scrollLock );

var scrollLock = function(e) {
        if( $body.hasClass('menu-open') ){
                e.stopPropagation();
                e.preventDefault();
        }
};

$html.unbind('touchmove', scrollLock );
Squiggs.
  • 4,299
  • 6
  • 49
  • 89
0

I've been having some trouble with it too but in a slightly different scenario.

I do have my divs with inertia without any problems.

I have a simple JSFiddle where you can have a look.

https://jsfiddle.net/SergioM/57f2da87/17/

.scrollable {
    width:100%;
    height:200px;
    -webkit-overflow-scrolling:touch;
    overflow:scroll;
}

Hope it helps.

SergioM
  • 1,595
  • 1
  • 15
  • 27
0

I used the last method in mohammed Suleiman's answer (.dashboardScroll:after { height: calc(100% + 1px);}) but the result was that I had a 100% + 1px empty space below my content. I fixed this by changing height back to 1px after 500ms. Ugly, but it works.

This was a react.js app so my code was like this:

componentDidUpdate() {
    if (window.navigator.standalone && /* test for iOS */) {
        var self = this;
        setTimeout(function(){
            self.refs.style.innerHTML = "#content::after { height: 1px}";
        }, 500);
    }
}

and render:

render() {
    var style = '';
    if (window.navigator.standalone && /* test for iOS */) {
        style = "#content::after { height: calc(100% + 1px)}";
    }
    return (<div>
                <style type="text/css" ref="style">
                    {style}
                </style>
                <div id="content"></div>
            </div>);
}
Dagligleder
  • 451
  • 5
  • 14
0

I had this problem while using the angular bootstrap modal. I fixed it by creating my own stylesheet and removing the fixed width and margin in the media queries.

ORIGINAL:

  .modal-dialog {
    position: relative;
    width: auto;
    margin: 10px;
  }

@media (min-width: 768px) {
  .modal-dialog {
      width: 600px;
      margin: 30px auto;
  }
    .modal-content {
        -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
    }
    .modal-sm {
        width: 300px;
    }
}
@media (min-width: 992px) {
    .modal-lg {
        width: 900px;
    }
}

CHANGES:

.modal-dialog {
    margin: 0px;
    margin-top: 30px;
    margin-left: 5%;
    margin-right: 5%;
}

@media (min-width: 768px) {
    .modal-dialog {
        width: auto;
        margin-left: 10%;
        margin-right: 10%;
    }
    .modal-content {
       -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
       box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
    }
}

@media (min-width: 992px) {
    .modal-dialog {
        width: auto;
        margin-left: 15%;
        margin-right: 15%;
    }  
}
0

i fixed my issue by adding some inline css to the scrollable div with jquery.. adding the css to the div after the dom is loaded makes scrolling work.

$('.lightbox__scrollable-content').css('overflow-y', 'scroll');
0

My problem was that the body had position:fixed that came from body-scroll-lock.js. Removed it and everything worked fine.

doğukan
  • 23,073
  • 13
  • 57
  • 69