Grow your CSS skills. Land your dream job.

Last updated on:

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. 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.

    • 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.

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

  2. 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.

  3. 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.

    • 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.

    • 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().

  4. Irfan
    Permalink to comment#

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

  5. 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. Andy
    Permalink to comment#

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

  7. Permalink to comment#

    Thanks! So relieved CSS fixes this!

  8. 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.

  9. 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. Kiran
    Permalink to comment#

    Thanks buddy!

  11. 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. 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

    • 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. 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/

    • 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.

    • 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. 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?

    • 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. Warren
    Permalink to comment#

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

  16. 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. 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.

  18. 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. 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. Ahmet Sali
    Permalink to comment#

    works great on ipad, thanks for the tip.

  21. Nathan

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

  22. 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. 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!)

  24. 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.

    • 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.

  25. 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. 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. 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. Fredrik

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

  29. Saved my week !!!

  30. Tobias
    Permalink to comment#

    Thanks Chris, just made my day too!

  31. 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. Capital Themes
    Permalink to comment#

    Wow, that was a life saver.

  33. 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. pankaj
    Permalink to comment#

    why overscroll scroll?

  35. 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. Permalink to comment#

    Love it! Worked Thanks! :D

  37. Eugene Yu
    Permalink to comment#

    I love you

Leave a Comment

Posting Code

Markdown is supported in the comment area, so you can write inline code in backticks like `this` or multiline blocks of code in in triple backtick fences like ```this```. You don't need to escape code in backticks, Markdown does that for you.

Sadly, it's kind of broken. WordPress only accepts a subset of HTML in comments, which makes sense, because certainly some HTML can't be allowed, like <script> tags. But this stripping happens before the comment is processed by Markdown (via Jetpack). It seems to me that would be reversed, because after Markdown processes code in backticks, it's escaped, thus safe. If you think you can fix this issue, get in touch!

If you need to make sure the code (typically HTML) you post absolutely posts correctly, escape it and put it within <pre><code> tags.

Current ye@r *

*May or may not contain any actual "CSS" or "Tricks".