Momentum Scrolling on iOS Overflow Elements

Web pages on iOS by default have a "momentum" style scrolling where a flick of the finger sends the web page scrolling and it keeps going until eventually slowing down and stopping as if friction is slowing it down. Like if you were to push a hockey puck across the ice or something. You might think that any element with scrolling would have this behavior as well, but it doesn't. You can add it back with a special property.

.module {
  width: 300px;
  height: 200px;

  overflow-y: scroll; /* has to be scroll, not auto */
  -webkit-overflow-scrolling: touch;
}
Check out this Pen!

Comments

  1. User Avatar
    David Pett

    Hey Chris,
    Is there a way to prevent the momentum scrolling on desktop (using a magic mouse or trackpad) as well as on iOS? I have been searching for a long time, but without luck.

    • User Avatar
      Lasha
      Permalink to comment#

      Hey David, you can implement a scroll debouncer that can limit to only 1 scroll event being run every few milliseconds. Thing is, it will be far from perfect and in several cases may feel pretty unnatural.

      Perhaps I’ll write a simple tutorial for this.

    • User Avatar
      Federico B
      Permalink to comment#

      Why would you ever want to do that? That’d be the most annoying thing.

    • User Avatar
      sheriffderek
      Permalink to comment#

      You could check for touch events with modernizr or something like it, and then only apply the rule in certain cases.

    • User Avatar
      Ralph
      Permalink to comment#

      Checking for touch events is unreliable. Too many false positives and even at Modernizr they don’t recommend it.

    • User Avatar
      Samuel Fonseca
      Permalink to comment#

      Hey, you could try to use @media feature to see the size of your screen and if it is so small then the code works, but if it is bigger than x value it will not work, for example:

      @media screen and (max-width: 768px) {
              .touch {
                   -webkit-overflow-scrolling: touch;
              }
      }
      

      That will only apply to a screen size max of 768px. That’s the simplest way, and it is how many websites do it

  2. User Avatar
    Chandra

    Chris, momentum scrolling doesn’t seem work inside an iframe. I’ve tried several settings, I’ve also tried to iframe in the demo,

    http://playground.johanbrook.com/css/touchtest.html

    But it doesn’t produce scrollbars 99% of the time. Looking into a hack.

    • User Avatar
      Dario Corno
      Permalink to comment#

      Chandra, did you find a solution to touch scrolling on iframes? I’m getting mad after the same problem…

    • User Avatar
      Kristie
      Permalink to comment#

      Yeah, it doesn’t work on iframes. If you wrap the iframe in a container and put the -webkit-overflow-scrolling: touch and overflow-y: scroll on that, it should work. See this Codepen.

    • User Avatar
      Kathleen
      Permalink to comment#

      Kristie, thanks for the codepen example – it totally solved our problem!

    • User Avatar
      Dave
      Permalink to comment#

      Thanks this works perfectly!
      Do you have anything to resolve the milisecond lag when clicking on a link on a touch device?

  3. User Avatar
    Jesse Dijkstra
    Permalink to comment#

    I’m currently using webkit-touch-scrolling to increase performance the performance of scrolling in iPad and iPhone web applications. It has significantly increased performance, but just like most applications that use a timeline like environment with images, the iPad runs out of memory when a lot of ’tiles’ have loaded.

    Is there any way to track the scroll position when momentum scrolling? Much like the ‘touchmove’ and ‘scroll’ event? So far I have seen lot of no’s.

    My current solution would be to set a variable when the user starts scrolling and set a setTimeout() to an X amount of milliseconds to ‘simulate’ the scroll function.

    • User Avatar
      caleb
      Permalink to comment#

      This is just a little side note, the reason you run out of memory is because apple will only allow you to have 10 mb of ram with web applications. Why would they let you create native like applications on the web? If you could, there would be no reason to pay to be in their app store. We need to hold them accountable.

    • User Avatar
      Arve Seljebu

      Had the same problem as you, iOS safari crashing. I debugged this for over a day, because I was sure the memory crash was due to hundreds of Angular hg-repeat elements(empty ones, which loads images upon scroll position).

      The funny thing is, when debugging this in iOS Simulator, it doesn’t occur! Another funny fact is that I went from a menu with position:fixed, because the menu pops down when a input field is activated(rendering halts upon window resize), but at the same time changing the input field to a select field which doesn’t pull up the keyboard. So all i all, I just implemented a bug which wasn’t even needed, argh!

      For others that might search for this, I will include that the browser crashed upon invoking $location.hash(id) and $anchoScroll().

    • User Avatar
      frank
      Permalink to comment#

      happy

  4. User Avatar
    Irfan
    Permalink to comment#

    I tested your demo on Windows Phone (IE10) and both divs. scrolled kinetically.

    • User Avatar
      Me Ted
      Permalink to comment#

      This is only an issue with iOS. Both Android and WP behave properly without the use of ridiculous proprietary styles.

  5. User Avatar
    Marcello
    Permalink to comment#

    Exactly what I needed, Chris!

    And I think you might be from the future, because you always seem to foresee what I’m going to need next. Very appreciated, man!

  6. User Avatar
    Andy
    Permalink to comment#

    So incredibly helpful. Thank you!
    I was wondering how I managed to accidentally disable the momentum scroll.

  7. User Avatar
    Sarah
    Permalink to comment#

    Thanks! So relieved CSS fixes this!

  8. User Avatar
    Annie
    Permalink to comment#

    Every time I try this style out, some of the content on some of my pages just disappears –– has anyone else had this problem? The elements that disappear still take up space (so it’s not like they’re display:none;) I can see the content when I look in Chrome’s inspector window, and the yellow indicator points to where my content is supposed be, and it basically points to these invisible divs that have height:0px;

    It’s definitely these “momentum scrolling” styles causing this. I’ve tried only deleting those styles, and my content comes back, but then goes poof when I add the them again.

    Because I wanted the whole page to have the momentum scrolling, this is how I did my styles:

    * {overflow-y: scroll; 
    -webkit-overflow-scrolling: touch;
    

    Any ideas what I might be doing wrong? Any thoughts much appreciated.

    • User Avatar
      Annie
      Permalink to comment#

      Oops – nevermind! Tried adding the style to html instead, worked like a charm. Duh

    • User Avatar
      Oattie

      Yup, you got it right Annie: thanks! It works like a charm. :)

    • User Avatar
      Alex
      Permalink to comment#

      Hey! I sat next to you at the jQuery conference in San Diego! lol

  9. User Avatar
    Claudio
    Permalink to comment#

    Thank you Annie! I’ve fixed my issue! Change the -webkit-overflow-scrolling to none before to change overflow to hidden so I can prevent the disappearing :)

  10. User Avatar
    Kiran
    Permalink to comment#

    Thanks buddy!

  11. User Avatar
    Alex
    Permalink to comment#

    I noticed that using overflow-y: auto; (from Chris’s example) also works. Tested in the native browser and Chrome of a Samsung tablet with Android 4.0.4 and also on iPad with iOS 6, Safari + Chrome.

  12. User Avatar
    Balbir
    Permalink to comment#

    overflow-y: auto; is working on all browser for me but not working on iPad. I am using following Style:

    .m-scrollable-filter {
    overflow-x: hidden !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
    }

    pls give me any response.

    Thanks

    • User Avatar
      Lachlan
      Permalink to comment#

      Chris said in the article that overflow-y must be set to scroll for -webkit-overflow-scrolling: touch to work. So use this code instead (there’s no need for !important):

      .m-scrollable-filter {
        overflow-x: hidden;
        overflow-y: scroll;
        -webkit-overflow-scrolling: touch;
      }
      
  13. User Avatar
    James
    Permalink to comment#

    Anyone have this associated issue and know how to prevent it (or what I’m doing wrong)?…

    I have a div within a wrapper div which specifically allows horizontal scrolling but prevents vertical scrolling. Everything is fine except that on ipad it remains possible to vertically lift the entire div, which then bounces back on release. What is more annoying is that this then allows the same div to ‘drag’ diagonally with a diagonal swipe. Here’s the page in progress…

    http://raewilkinson.scratchthesky.com/

    • User Avatar
      James
      Permalink to comment#

      I fixed this issue with javascript that prevents the default scroll-bounce behaviour in the vertical axis. It works but it’s not ideal. I still have no insight into how the entire div could become ‘dragable’ in every direction.

    • User Avatar
      awe

      I had the other case where the content was scrollable in vertical direction. I had this style applied:

      overflow: scroll;
      -webkit-overflow-scrolling: touch;
      

      Even when there were no need for horisontal scroll, it behaved like if you drag horizontally it moves the content sideways and bounce back. I solved this by doing:

      overflow: scroll;
      overflow-x: auto;
      -webkit-overflow-scrolling: touch;
      

      This cause momentum to be used only in y-direction, since momentum is disabled when setting overflow to auto.

      You can set it the other way: overflow-y:auto to only use momentum in x-direction.

  14. User Avatar
    Adrian
    Permalink to comment#

    If I add this:
    overflow-y: scroll; /* has to be scroll, not auto */
    -webkit-overflow-scrolling: touch;
    to the html, or body, or any major block of my website I get no scroll improvements and I cannot tap on the top bar to scroll to the top. Any idea why?

    • User Avatar
      Lachlan
      Permalink to comment#

      You don’t need to add it to html or body on your webpages; Apple uses momentum scrolling on all pages automatically. -webkit-overflow-scrolling: touch is just for scrolling other elements on the page (only being able to scroll, say, a p). Also, touch scrolling gives no “scroll improvements” — it just lets you flick your finger to quickly get through something long.

  15. User Avatar
    Warren
    Permalink to comment#

    Thank you very much for this, exactly what i needed for fixing the scrolling issue on ios.

  16. User Avatar
    Mike in NY
    Permalink to comment#

    Hey — Just thought id take a second to say THANK YOU for this … as much as it seems i should have already known about the -webkit property, had i not seen this i may very well have gone down a dark road trying to implement a javascript replacement for overflow-y … THANK YOU SINCERELY

  17. User Avatar
    Jamie
    Permalink to comment#

    Just a warning for folks out there finding this great feature – if you are using it in a rule that also includes overflow-x: hidden – beware. Because the -webkit-overflow-scrolling: touch property will allow the user to scroll vertically and horizontally, which may reveal hidden divs that are meant to be hidden to the left or right.

    • User Avatar
      Philip
      Permalink to comment#

      I am facing this exact problem. I loose the vertical momentum scrolling as soon as I add overflow-x: hidden to the html and body tag. Adding -webkit-overflow-scrolling: touch restores the vertical momentum scrolling but breaks my overflow-x: hidden. Is there a way to get away with both? I tried to place the two styles at different places, in the html tag only, in the body tag only, in a wrapper div, always with no luck.

  18. User Avatar
    Kaushi
    Permalink to comment#

    Does any one know how to add a auto scrolling function to a horizontal scroll bar???I have some images in a table row and i want that row to auto scroll horizontally but not manually..
    Please help me

  19. User Avatar
    tushar
    Permalink to comment#

    I have customize scroll using CSS3, its working fine in all browser but the overflow-x is not visible in iphone. Here is the code what I have done. http://codepen.io/anon/pen/aLwhq

  20. User Avatar
    Ahmet Sali
    Permalink to comment#

    works great on ipad, thanks for the tip.

  21. User Avatar
    Nathan

    Thank you, this fixed a problem I was having and now the iPhone page looks like it should!

  22. User Avatar
    Charles

    Okay, so when I have overflow-y: scroll; and -webkit-overflow-scrolling: touch; it works fine in most cases… except on the DIV I actually need it.

    It’s a fixed DIV. When I load the page in landscape, and there is enough content to need overflow it works, but if I then change the device orientation to portrait (where the content doesn’t need overflow) then back to landscape the DIV no longer scrolls at all!

  23. User Avatar
    Charles

    Please reply on this comment to above comment so I get notifications :P (I wish there were a way to edit such preferences on here!)

    • User Avatar
      Nishant

      Hi Charles,
      I am also having this same issue, have you got any solution for this?

  24. User Avatar
    Earl

    This was a great find — worked as promised. The only side effect is that child elements with position: fixed now move with the parent’s scrolling, until the momentum stops, and then they snap back into their fixed positions.

    • User Avatar
      James Hilton
      Permalink to comment#

      Did you ever find a solution to this? I’m having the same issue with a position:fixed navigation header div positioned on the top.

    • User Avatar
      Jonathan
      Permalink to comment#

      I’m having a similar issue. Fixed child element in container that that has “-webkit-overflow-scroll” moves while scrolling, and in addition, it’s hidden (I think the latter issue is related to z-index being changed when “webkit-overflow-scroll” is applied.

  25. User Avatar
    Andrew Robert Burgess
    Permalink to comment#

    I can confirm that

    overflow: auto;
    -webkit-overflow-scrolling: touch;

    Works if you don’t want to show scroll bars all the time. Thanks for the tip, Chris!

  26. User Avatar
    Joshua
    Permalink to comment#

    Thanks for the tip Chris;

    overflow: auto;
    -webkit-overflow-scrolling: touch;

    works fine for iPhone media query;
    but when I used it within media query for iPad (1,2), it was causing the iOS app that was loading the page through iframe, to crash.

  27. User Avatar
    Manikandan
    Permalink to comment#

    Hello All,

    It works great for me. But I have another problem.
    While creating custom scroll, I’m unable to get smooth scrolling.
    Did I miss something?

  28. User Avatar
    Fredrik

    Saved my day! However why I would need to add this in the first place is beyond me

  29. User Avatar
    Laurent Perroteau

    Saved my week !!!

  30. User Avatar
    Tobias
    Permalink to comment#

    Thanks Chris, just made my day too!

  31. User Avatar
    Abid
    Permalink to comment#

    Bundle of thanks!

    Dear your technique works for me. i was facing problem in scrolling on touch devices, then i give your code to“`

    body {overflow-y:scroll}

    “`
    now my website scrolling smooth now.

  32. User Avatar
    Capital Themes
    Permalink to comment#

    Wow, that was a life saver.

  33. User Avatar
    Brenton
    Permalink to comment#

    Why in the world would you disable inertial scrolling by default? Who thought “This developer clearly wants this thing to be scrollable, but he probably wants it to be janky, so let’s make that the default.”?

  34. User Avatar
    pankaj
    Permalink to comment#

    why overscroll scroll?

  35. User Avatar
    Zvi
    Permalink to comment#

    Thanks for this, just saved me a few hours. Thanks also to the keywords that got me here.

    Crazy how specific some of the controls can be.

  36. User Avatar
    Isham
    Permalink to comment#

    Love it! Worked Thanks! :D

  37. User Avatar
    Eugene Yu
    Permalink to comment#

    I love you

  38. User Avatar
    Tom Dobbs
    Permalink to comment#

    You just saved me hours of futzing around. Again. Thanks!

  39. User Avatar
    Adrian
    Permalink to comment#

    Thank you verry much!
    Keep on going with this good work, great article!

  40. User Avatar
    launchoverit
    Permalink to comment#

    Words cannot express how grateful I am for this. Thank you!

  41. User Avatar
    Todd
    Permalink to comment#

    I have a strange problem. I’ve tried looking everywhere and I can’t find any answers.

    I’m using this CSS property (-webkit-overflow-scrolling) in an iOS app loaded inside a web view.

    As soon as I open the app, it crashes and closes again. The crash report lead me to this page: http://bit.ly/1GobVK2 which suggests that it is caused by this CSS property. Is that legit? Should I continue to try and fix this based on this theory?

    Has anyone else had similar issues with this CSS property?

  42. User Avatar
    Mo

    Hey Chris,

    just wanted to say, it actually does work with overflow: auto;, I have it set up and working on a few sites.
    Thank you for this snippet – don’t know why, but I keep forgetting this exact declaration and come back every time I need it again. ;)

  43. User Avatar
    Anurag

    Hey Chris,

    This is really helpful. I was struggling for this issue and after applying -webkit-overflow-scrolling: touch; all the things stated moving smoothly. Thanks man for this :)

  44. User Avatar
    Liz
    Permalink to comment#

    Hi, I’m a real tech dummy, so can you please help me and put it really simply like go to settings, go to x, then x, etc. my iPhone 5s screen keeps scrolling and it’s driving me nuts! The screen is clean, it’s a year old. I’ve tried turning it off and on again, no joy. How do I fix it? If it’s a memory thing should I delete some aps? Thanks! :-)

  45. User Avatar
    Ryan Knell
    Permalink to comment#

    So yeah, didn’t read that it doesn’t work on “auto” and then tried it… Works on auto for me using Cordova on iOS so it might have changed, just a heads up.

  46. User Avatar
    Aj
    Permalink to comment#

    https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-overflow-scrolling

    There seems to be a warning on the page to not use ‘-webkit-overflow-scrolling’ on production facing sites.

  47. User Avatar
    Christopher Bartlett
    Permalink to comment#

    Thank you! This worked perfectly!!

  48. User Avatar
    Diego
    Permalink to comment#

    What a nice solution, it worked perfectly! Thanks!

  49. User Avatar
    kirk
    Permalink to comment#

    Hi – when i use -webkit-overflow-scrolling on a div on ios 9+, cordova app it only activates scroll on 2 finger drag. any ideas on a work around?

  50. User Avatar
    Ferdy Christant
    Permalink to comment#

    I know that this is an old post, but…

    “Web pages on iOS by default have a “momentum” style scrolling where a flick of the finger sends the web page scrolling and it keeps going until eventually slowing down and stopping as if friction is slowing it down. Like if you were to push a hockey puck across the ice or something”

    …I believe this statement is actually false. Take any web page, including this very website, and scroll it in mobile Safari. It will not have inertia scrolling. Scrolling stops almost immediately when you lift your finger. Inertia scrolling at the page level isn’t a default at all.

    Unless of course I am crazy and am the only person getting these results. Tested in iOS 7, 8 and 9, on 3 devices.

    My finding is that you actually do have to use webkit-overflow at the document level. And because most sites don’t, they are seriously missing out.

    • User Avatar
      Wowbagger
      Permalink to comment#

      Helped me a lot. I went from scrolling divs to scrolling page, so now it works on iOS. Has worked perfect on android from the beginning.

  51. User Avatar
    J Henckel
    Permalink to comment#

    I love you!! just what I needed. you saved my app.

  52. User Avatar
    Ferdy Christant
    Permalink to comment#

    It seriously makes a world of difference to enable it, since it really isn’t a default. More info here:

    https://ferdychristant.com/the-world-s-most-overlooked-web-optimization-for-ios-d88c7517d520#.r6pijsei7

  53. User Avatar
    Carlos Ballena

    This fix no longer seems to be working.
    – Is anybody experiencing the same issue?
    – Does anybody know how it could be fixed now?

    • User Avatar
      Jesse
      Permalink to comment#

      Seems to be working on my iPhone SE, just not on my desktop Mac.

  54. User Avatar
    Sriram Krishnan

    is there a way to make momentum scrolling work and hide the scrollbar permanently ?
    I tried using ::-webkit-scrollbar et all – looks like they are not compatible with
    -webkit-overflow-scrolling: touch;

  55. User Avatar
    Rachel

    Does anyone know how to get topbar and bottom bar for iphone to hide? In iOS 9 it is standard, but with this scrolling that standard disappears..

  56. User Avatar
    Rick Snackers
    Permalink to comment#

    You saved me again. Thanks!

  57. User Avatar
    senthil kumar
    Permalink to comment#

    Try this it’s working for me

    if (window.location == window.parent.location && navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
    $(‘#orderpop’).attr(‘style’, ‘-webkit-overflow-scrolling: touch !important; overflow-y: scroll !important;’);
    }

    preventScroll : function(prevent) {
        var body = $('body'), html = $('html'), scroll;
        if (prevent) {
            var width = body.css('width');
            scroll = window.pageYOffset;
            // This is all you need to do to prevent scroll on everything except iOS.
            html.css({ 'overflow': 'hidden'});
            // For iOS, change it to fixed positioning and make it in the same place as
            // it was scrolled.
            // For all systems, change max-width to width; this prevents the page getting
            // wider when the scrollbar disappears.
            body.css({ 'position': 'fixed', 'top': -scroll, 'max-width' : width});
        } else {
            scroll = -parseInt(body.css('top'));
            html.css({ 'overflow': '' });
            body.css({ 'position': '', 'top': '', 'max-width': '' });
            window.scrollTo(0, scroll);
        }
    },
    

    });

  58. User Avatar
    Tony
    Permalink to comment#

    What about other prefixes, -moz-, -khtml-, -o-, -ie-, or is this specifically for safari only? Does this need to be done for android too? What other prefixes would be needed for those?

  59. User Avatar
    sinneren
    Permalink to comment#

    Thid demo and in my project don’t work on iPad(MD329LL/a) with 7.0.4(11B554a)

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

Submit a Comment

icon-closeicon-emailicon-linkicon-menuicon-searchicon-tag