Scrolling div on iPhone/iPod Touch

Recently I had to develop a web application for the iPhone and I was impressed by the possibilities offered by the little device. You can easily render complex 3d animations with a bunch of CSS rules or save data on a sqlite database, but I was surprised to discover that there is no easy way to scroll the content inside a fixed height div.

Update 2009/11/30: Development of iScroll v3.0 has been started. Please head to the new version. This post will be soon obsolete.

Update 2009/01/07: Thanks to a mighty commenter the scrolling function has been updated.

Update 2009/01/18: Look Ma, without timers! The script has been updated once again. I got rid of the timer I used to reset the touchMove action, now we are timers-free. Additionally all the nasty anonymous function calls have been removed and replaced by the chic code suggested by Antoine Quint.

Update 2009/02/03: Kudos to Andreas Ritter that managed to optimize the deceleration formula. Now the script mimics very closely the native iPhone scrolling. Other small enhancements have been done, so be sure to download the latest version of the script at the bottom of this post.

Update 2009/02/12: autoScroll renamed to the fancier scrollTo. By popular demand I added the refresh() method that should be called each time the scroller content is programmatically modified (by an ajax call for instance). Code released under the MIT license (so you can pretty much do anything you want with it).

Update 2009/06/18: the script has been finally updated for OS3.0 compatibility.

Update 2009/07/09: it turned out that Apple is well aware of the webkit refresh bug, fortunately they are kind enough to offer a workaround. All we have to do is to use translate3d instead of translate and all our animations will be fluid as never before! Go get the latest version of the script!

Apple disabled all the scrolling functionalities on the webkit for iPhone, javascript functions and events included. So basically you can scroll the whole screen with one finger but to scroll elements inside the page (e.g. iframes) you have to use a two-fingers gesture.

While this is perfectly logical on a standard web page, can be limiting on a web application. Let’s say you want a fixed position header or footer and a scrolling center area, well… you can’t. (Did I say that position:fixed does not work?). Many iPhone behaviors are triggered with meta tags, or CSS directives or javascript but as far as I can tell there is no easy way to scroll content inside a fixed size div.

Fortunately we can take advantage of the powerful javascript engine and some hardware accelerated animations. The good news are that the script is compact (4kb uncompressed/unminified), self contained and the scrolling extremely smooth. The bad news is that it’s actually a β€œhack” so it’s not perfect (see below) but usable.

Enough blabbing. Point your iPhone, iPod touch or emulator to my working demo or watch the quick screencast. If you are curious about how the script works read the following chapter, otherwise skip to How to use the script.

How it works

The latest iPhone update (2-point-something) added touchstart, touchmove and touchend events. We hook at those events to capture finger movements and use the -webkit-transform CSS property to translate the div content up and down simulating the scrolling. You can easily expand the script to scroll in any direction, but I leave this task to the diligent reader πŸ˜› .

e.preventDefault(); prevents the whole page to scroll but it also disables all the useful events we may need. Most notably the mouse click (or finger tap) is not executed so we have to simulate it.

On touchend if no scrolling is due I try to create a new mouse click with the following:

var theTarget =;
if(theTarget.nodeType == 3) theTarget = theTarget.parentNode;
var theEvent = document.createEvent("MouseEvents");
theEvent.initEvent('click', true, true);

The click is cast indiscriminately, not only over β€œclickable” objects (such as anchors or buttons). I bet there is a fancier way to do that, none that I could find though.

To simulate the scrolling deceleration I initially used a timer but the script has been recently updated after a reader suggested to use window.getComputedStyle() to get the in-transition position. This brilliant solution removes the timer but needs an additional event listener. I don’t know which solution consumes less resources, but the new version seems more logical as it relies completely on -webkit-transform for animations and transitions.

The core of the new code is:

var theTransform = window.getComputedStyle(this.element).webkitTransform;
theTransform = new WebKitCSSMatrix(theTransform).m42;
    if( theTransform!=this.position )
        this.position = theTransform;

webkitTransform returns a matrix of all the transformations applied to an object. All we need is the Y position which is stored in WebKitCSSMatrix(theTransform).m42. If the user taps the screen while the animation is rolling, the transition stops and content holds its position.

How to use the script

On the HTML side all you need is a fixed size element that wraps the scrolling area.

<div id="wrapper">
    <div id="scroller">

The wrapper needs the following styles:

#wrapper {
height:200px;        /* Desired element height */

Remember to give the #wrapper a z-index.

The #scroller does not need any style at all. You don’t even need to make it position:absolute as everything is handled by -webkit-transform.

To activate the scrolling add on window load:

new iScroll(document.getElementById('scroller'));

It’s better to let the window rest few milliseconds before running the script:

window.onload = function() { setTimeout(function(){ new iScroll(document.getElementById('scroller')) }, 100) };

If the content of the scroller changes on the fly for any reason (eg: http request), remember to call the refresh() method, it takes care of some variables initialization.

As a bonus feature you can scroll to any position programmatically by calling the function scrollTo(destination, duration) (see the example for details).

Known issues and limitations

The standard pop up that appears when holding on anchors does not come up (does anyone care?).

Text fields inside the scrolling area behave weirdly (but probably it can be fixed).

Remember to add a timeout on window load. In my experience the onload timeout needed by webkit to be really helpful is 100ms minimum. (That is a bit more than I hoped).

Please note that the iPhone can’t handle too many objects in the scrolling area. For best performance remove all unneeded tags from the scroller.

The script is not perfect and maybe not even elegant, but it works pretty well. I hope you can use it as a starting point and save few hours programming. If you have any advice to improve my code, please leave a comment.

Download the script

152 thoughts on “Scrolling div on iPhone/iPod Touch”

  1. > CSS transform is a great feature but has its limits. It lets us easily move objects with nice animation but we cannot get the object position during the transition.

    It is possible to get the in-transition position:

    var theTransform = window.getComputedStyle(theObject,null).getPropertyValue("-webkit-transform");

    You should then be able to stop the transition by applying the returned value as current value:"-webkit-transform", theTransform);

  2. Andi,
    if that’s true we can greatly enhance the script performance. I’ll give it a try right away.

    UPDATE: I updated the script, but things got a little more complicated. Anyway in the next few days I’ll try to make it simpler.

  3. Very nice work!

    I think you could improve the script by removing the use of anonymous functions the way I descibed it in a recent post on the iPhoneWebDev group:

    The changes would be as follows.

    In the constructor:

    this.element.addEventListener('touchstart', this, false);
    this.element.addEventListener('touchmove', this, false);
    this.element.addEventListener('touchend', this, false);

    and then add the following method on iScroll.prototype:

    handleEvent : function (event) {
      switch (event.type) {
        case 'touchstart' :
        case 'touchmove' :
        case 'touchend' :

    But that’s more of a technicality, very nicely done.

  4. thanks Antoine, very smart code indeed. I am writing a tutorial for creating an ABC control ala “contacts list” using this script. I will update the code with your suggestions in that occasion.

  5. Although It make a mouse event by document.createEvent and dispatchEvent, the event works wee. But the display is incorrect.

    for example:
    <div id="wrapper" >
    <div id="scroller" >
    <div ><input type="checkbox" id="chk1" value="1" > </div >
    <div > <input type="checkbox" id="chk2" value="2" > </div >
    ……(total 100) …
    <div > <input type="checkbox" id="chk100" value="100" > </div >
    </div >
    </div >

    if you click on each checkbox, the status of checked is correct but display may not. It display correctly in nth checkbox (show in first display) but it display incorrectly after nth checkbox(not show in first display). This may be the bug of safari.

  6. @felka,
    It’s a webkit refresh problem (I’d say “bug”) related to the translate() function. I noticed that if you change the top attribute instead of -webkit-transform, elements on screen seem to refresh correctly. All you have to do is change the set position(pos) portion of code. Unfortunately translate() is a bit faster. Maybe I could publish the two alternatives.

  7. @alektraunic,
    The script is self contained and does not rely on any javascript framework (and it does not interfere with any of them). The jQuery version would just make it slower. The only reason I can think of for making a jquery plugin is to create a cross-browser version of the script.

  8. just playing around a bit

    The weight of jQuery could be an issue for a production app, but for proof of concept work it gets the job done.

    As a bonus, if you click the “+” in mobile Safari, “Add to Home Screen” and create an icon, the page will load from that icon without any Safari chrome at all, essentially it will look just like a downloaded app.

  9. Hello,

    First off, thanks for this tool, I am also an advocate of going with web apps rather than native apps, so making this look/feel like the native app scrolling is awesome.

    I ran into a few issues, fixed some, and still trying to fix others but I’m just gonna post one of the issue fixes here in case someone else runs into the same issue.

    #1. If the scroller div has no height set, and the contents are less in height than the wrapper and the user scrolls up, the scroller div will shoot to the bottom of the wrapper div, rather than stay aligned to the top.

    solution: either define the height for scroller to be equal to the wrapper in the css OR, you can use javascript to set the height.

    #2. If you try to dynamically add items to the scroller div (for ajax or whatever other reason) the height is not compensated, so if you had nothing inside the div and added something, scrolling will go crazy.

    solution: need to set the height with javascript after you have added content.

    *note: if you do reset the height of the scroller, the “new iScroll(document.getElementById(‘scroller’));” function must be run again.

    PS. Sorry for the long post. I don’t know a better way so far, but thought I’d throw it out there.

  10. Alex,
    stay tuned as I am already working on the two issues you outlined. #1 is solved by just disabling the scrolling if the scroller height is lesser than the container height. For #2 there are two possible solutions: 1) recalculate the scroller height at each touchstart (which I don’t like much); 2) create a refresh method to call from your script each time the content of the scroller is changed (eg: myScroll.refresh()).

  11. That refresh method turned out wonderfully. For the first problem, I actually still wanted a scroll just to make it more like the iphone. I ended up just adding a div in the scroll div that is the height of the container – scroller and it worked out well. Cheers!

  12. As it is right now the script only handles vertical scrolling. This has been done to reduce the device stress to the minimum. Anyway it’s pretty simple to add horizontal scrolling (I’d say a dozen lines of code).

  13. hmm, I’ll have to dive in and see if I can make it happen with my limited js knowledge. Should be interesting to see if the iphone chokes on it or not.

  14. This is nice code. Thank you very much for the good work.

    Have you looked at implementing the tapping mechanism to automatically scroll 1 page whenever someone taps the page? It makes it easier to read longer text.

  15. pw,
    I haven’t thought about that, but it’s pretty easy to implement. There’s no “doubleTap” event, though, so it must be emulated.

  16. Very nice script. A couple of issues which are really just side effects. If you use window.scrollTo to remove the address bar (before instantiating this script), you won’t be able to get back the address bar, obviously. Also, If you have images that are larger than the screen, you can’t scroll around or zoom to view the image. I haven’t figured out a good way around either yet.

  17. @b,
    they can’t be considered “bugs” per se. To get the address bar back you could keep the header of your page outside of the preventDefault that prevents the screen to scroll. So the user has a small area that can use to scroll the whole page.

    If you have content that goes outside of the viewing area you need to implement both x and y panning (to scroll around). Zooming is a bit complicated… but maybe can be done hand coding the gesture event.

  18. Just a question about this script. It works really well but I am trying to take an existing application that is based upon the browser application and use the scroller to create a navigation bar at the top or bottom. I haven’t figured out how to do this using this and was wondering if you might have some ideas.



  19. @Gil,

    <div id="header">header</div>
    <div id="content">
    <div id="scroller">
    <div id="footer">footer</div>

    This is really all you need. onLoad and onOrientationChange you’ll probably want to resize the “content” to fit the whole screen height.

  20. Hey there. I have tried doing this myself but have failed.

    The problem is to do with active elements. I am using a list with :active for the hover. As soon as your finger goes down, the element changes and continues active as you scroll. Would it be possible if you could make it so that when you touch one of these list items it applies a class that says the element is active and remove it when you scroll or when you release your finger.

    I only seem to be able to get the scroller div with this.element and not any elements within it that are directly tapped on.

    I had encountered a scrolling script which accomplishes this but the script does not work as well as this one but i had trouble integrating the adding and removing class part with yours.


  21. Hey scratch that last part. I have finally done it, albeit rather crudely for now. Thank you very much for this amazing script. I can now create the most awesomest web app ever πŸ˜‰

  22. One more issue that is an odd one. Animated gifs, that I’m swapping in using an onclick handler, don’t animate, at least when I have to scroll to see the link I’m swapping with. I’ve been trying to get this to work for hours today… and yesterday. I’m passing “this” to a function when you click on an image. Then, setting img.src to the image href. It loads, but won’t animate. It does animate if it’s at the top of the scroll div.

  23. @Aresinferno, glad it worked. Please keep me updated about your web app.

    @B, That is a well known webkit refresh bug. A solution could be to place dynamic objects top:0; left:-9999px and reposition them in right place on page load. Also changing the visibility from hidden to visible sometimes works. The bottom line is to force the browser to refresh the object in some way.

    @i, it should work, can’t see any reason why it shouldn’t.

  24. @Matteo Spinelli

    thanks for the reply, i didnt look into it in-deepth but just did a quick modification on iUI’s samples (, it didn’t seem to work well, iUI heavily hackjecks onclick event and treats all link clicks as ajax calls, it inserts new page as a div sector and only displays that sector… which means it may work on the first page but bottom bar will be gone on subsequent pages…

  25. What JavaScript specification does this target? Can you provide a link to some tutorials.

    I am trying to get the script to compile in IE and FF. Obviously the behavior will not work πŸ™‚

    Finally, are you still working on this script? Will you support horizontal scrolling?


  26. @KierenH, I’m afraid it targets webkit only (have a look at Apple’s developers site for details or As far as I know the desktop version of webkit does not support onTransitionEnd, so this script only works on the mobile version of webkit. It shouldn’t be that difficult to make a touchless version of the script anyway.

    I’m still working on the script, now I’m busy coding the spinning wheel, when it’ll be done I’ll probably try to add lazy loading to this scrolling script.

  27. Hello again. I just wanted to update you with my latest progress. Loading time can be slow but i guess adding that ontimeout at startup that you mentioned could speed things up a bit.
    It is more of a development kit right now but it will be a base that i create a web app off of. Unlike the other development kits out there this was first created primarily for fullscreen mode rather than created for safari and modded afterwards. I could mod it to work out of it but i don’t think it is worthwhile for now.

    Check this out:

    Just a temporary site as i work on it but i have successfully added the active elements that cancel as you scroll. Removed the callouts and highlights on links and made sure all links open in the current window rather than a new safari page unless specified with a class.
    Used onresize since orientationchange does not work in fullscreen. It resizes the elements depending on the width of the page to make the scrolling better. I will also modify the style of the footer to make it shorter like landscape safari.
    The header uses a crude script that centers itself between the left and right buttons and using text-overflow:ellipsis incase the header is too long.

    Not bad for a few days work and pretty good for someone who only understands limited javascript.

    My next project is databases and creating a manifest to make it completely offline if possible.

    Thanks so much for this script.

  28. Hi Matteo,

    Thanks for the info. That for some reason solved part of the problem.

    The problem I am running into is that the browser object (dashcode.browser) has a higher Z-index than the scroller (I think). If I grab the header of the browser it works fine and I can scroll. If I touch in the browser area (which is basically an unordered list), it doesn’t seem to work. I solved this by making the browser slightly smaller.

    The more annoying issue is that my lowest level doesn’t scroll through all of the data. I have 3 layers in my stacklayout which is beneath the browser layer. When I go to scroll the first two layers, there doesn’t seem to be a problem. The 3rd layer though only shows half the data. Since the scroller is for the entire application I thought it might have something to do with z-index. I set height to auto (and a ridiculously high number just for fun ) but it still doesn’t scroll all of the way.



  29. One other thing I notice is that sometimes when I go back, from the detail level scrolling stops working. In fact, nothing works as far as clicking other than magnification. Clicking back from the 2nd level to the first doesn’t have this problem.

  30. hey,

    First let me aapreciate you for your excellent code,..

    Moreover,this works only on vertical scrolling,rather I need horizontal scrolling do.

    Do u have any alarm hitting you on that?

  31. @Aresinferno: keep up the good work!

    @Gil: contact me directly at matt3o at [the google mail domain] if you want and send me your code. I can’t follow you without a bit of reference.

    @arunkumar and everyone: okay okay… I got it… we need a horizontal scrolling πŸ˜› I’ll code it in the next days.

  32. Hi Matteo,

    Thanks for reply, me too diving in to grab the solution.

  33. Update to the animated gif – It looks like anything that is animated or uses a timeout is stopped after the first iteration if it is contained within the scroller div (at least within a few pages of data). This doesn’t require a preloaded image to see.

    I tried a simple timeout that calls itself a few times and udpates a div. It goes one iteration and then stops. Works fine in other browsers. Is there anything in this code that would stop timeouts/intervals?

  34. @B, there’s nothing in the code that prevents timers or animated gifs. I guess it’s the refresh bug related to the translate() effect. It’s a well know webkit bug. Probably if you translate with instead of style.webkitTransform everything would work fine at the cost of scroll fluidity.

  35. I was not aware that you could get scrolling on the iPhone using divs. Just so everyone is aware:

    /* Scroll horizontally – div1content will be scrollable within div1. */
    overflow-x: scroll;
    overflow-y: none;

    width: 1000px;

    This works for 2 finger scrolling (two finger).

  36. Really appreciate the script! I was thinking of writing one just like it, and then ran across yours. I have used it successfully in a PhoneGap (WebKit Wrapper) native application for the iTunes App Store! Thanks!

  37. Any News on the Horizontal scrolling?

    This is fantastic BTW πŸ˜€

  38. This isn’t all that big of a deal, but I extended your script to allow a couple extra features…

    Just added a couple lines to verify something could be done:
    I like fixed backgrounds, sometimes. Also, fixed elements can be simulated with this too.

    And you can have multiple layered scroll regions, and still maintain the extra gestures, no need to disable taps on the whole document, if you don’t want to. Just adding a couple lines into the handle event:

    handleEvent: function(e) {
    	handled = false;
    	switch(e.type) {
    		case 'touchstart': this.onTouchStart(e); handled = true;  break;
    		case 'touchmove': this.onTouchMove(e); handled = true;  break;
    		case 'touchend': this.onTouchEnd(e); handled = true;  break;
    		case 'webkitTransitionEnd': this.onTransitionEnd(e); handled = true;  break;
    	if (handled) {
    		e.cancelBubble = true;
    		e.preventDefault(); return false;
  39. @Tom Pace,
    very nice addition indeed. Probably it should end up in the “official” release. I’ll also add 360deg scrolling soon. What I’d like to add is lazy loading, is not easy but can be done. That should greatly increase performance.

  40. After some testing it appears that if you call new iScroll several times (i tried on the same element) it slows down the scrolling alot. There is a large delay between scrolling and moving your finger. I am thinking an update iscroll command should not cause these problems if you just update the height of the scrolling content.

  41. This works on the latest development version of Android (“cupcake”) with a couple changes.

    First, the computed webkitTransform contained just a six-element ‘matrix(…)’, so I had to read element 5 instead of 13:

    var theTransform = parseInt(window.getComputedStyle(this.element,null).webkitTransform.split(‘,’)[5]);

    Second, removing the ‘touchmove’ and ‘touchend’ event listeners also stopped ‘touchstart’ events from being received. I haven’t figured out why that happens, but I was able to work around it by adding all three event listeners in the constructor, and never removing them.

  42. Sorry for repeating this Matteo, but is it possible to just update the scroll with a seperate command rather than calling the new iScroll. Every time iScroll on a certain element is called it slows the scrolling down even more.

  43. @Aresinferno,
    the scroll height is recalculated by calling the refresh() method (it is mentioned in the blog post). You should not re-instance the iScroll object. If you need any other type of refresh/update (eg: scroll to top every time you update the content) you should put it in the refresh() method.

  44. I have tried calling the refresh function and it never worked. Do i just call refresh() or whatever the element is .refresh()? I now see that the refresh also seems to be lacking some parenthesis.

  45. I guess i gave up on the refresh a little too soon. I see that i needed myScroll.refresh()

    Thanks matteo. Now fullscreen mode works perfectly and the wrapper automatically resizes to pagewidth – heade height – footer height.

    I can now webkit transform the element sizes and have it refresh the wrapper to fit. Finally got past this roadblock and starting to add list styles and page slide effects.

  46. great script!

    One problem though… I cannot use select lists with this code.
    No matter how many time i click it, it options dialog won’t trigger


  47. @Treason,
    Perhaps you could use the picker script instead that is located in a more recent post on this blog. It is very good and should work as you want.

  48. Matteo and Gil:

    Did you ever figure out the scrolling problem with stackLayout in dashcode? I am running into the same kinds of problems when trying to scroll. If I grab with two fingers it seems to scroll the list, but very badly. Only seems to be affecting lists as far as I can tell…

  49. This is a great piece of work. I think with some refinement it could be perfect. I’m having a couple of problems that I’m trying to solve, but I don’t think I’ll get there on my own as quickly as I’d like to.

    First, it seems to work pretty good in the emulator. But on my touch and phone I’ve come across a few issues. I’m using iWebKit to style my pages. When I go to scroll a list, sometimes it will highlight (although not click, hover maybe?) an item. This just looks kinda weird, especially since its inconsistent. Secondly, when I swipe to scroll sometimes it goes fine, but other times it just STOPS right where my finger came off the screen rather than continuing. Also, although the deceleration seems really good, on the phone it seems a bit to slow.

    I’m having problems with using this with text entries also, it does ALL KINDS of crazy stuff. Any idea what the basic source of the problem is for this?

    Thanx all!

  50. @treason: before theTarget.dispatchEvent(theEvent); try to add:
    if(theTarget.tagName=='SELECT') theTarget.focus(). I did not try by myself, but it could work.

    @flxkid: frameworks like iwebkit and iui expect elements to be placed in a very specific manner, it’s not easy to make them work with external scripts.

    That said, remember that the iPhone CPU can’t handle complex animations, so if you have too many objects to scroll the device will certainly lag.

    I’m also evaluating the possibility to develop a new framework for mobile webkit that integrates all the widgets I’m showing you on this blog. But it’s a lot of work, and I don’t know if there’s interest in something like this.

  51. @matteo,
    I am trying to do just that. I am creating my own kit for fullscreen mode utilizing you scripts and mine. Of course my scripts are rather crude at the moment. I am working on a script that gets the selected list, grabs the list you want from the href and sliding the elements as a page slide.

    My latest work is at

    It scrolls, auto adjusts the scroll area to fit the page height minus the header and footer heights and attaches ontouch and onclick events to elements. No hrefs do nothing except their onclick, hrefs beginning with # will slide and others will open a new page.

  52. Can anyone write horizontal and vertical scrolling code ? please paste it or told me how to do ,thx

  53. @matteo,

    I have just tried the demo (and my code) with the iPhoneOS3 beta and it doesn’t respond to my touch. Tapping the links on the bottom cause it to scroll, but I was have no luck scrolling with my finger.

    Sorry to be the bearer of bad news, but hopefully its a real simple fix.


  54. @Ron,
    thank you for your report. I was sure that os3 would have broken something, that’s why I am not updating this script until I put my hands on the new os. To my knowledge there’s no safari mobile 3 reference material, so –as always– it will be a trial and error work…

  55. @matteo,

    Thanks so much for your response. On the PhoneGap list, there are reports that transitions are broken in general. Theoretically, this should cause Apple to put out another beta pretty soon. However, the very fact that you (and some other wonderful folk) had to come up with this hack in the first place was because div scrolling doesn’t work, which is part of CSS3. Grrrr.

    I have been using your code to put a toolbar at the bottom of the screen. I *really* like the look of that, but I may have to rethink my GUI if we don’t hear from Apple soon. What I *really* want is to have the exact same look and feel in Safari on the desktop and Safari on the iPhone (and, to be really extravagant, the same as any WebKit browser).

    Again, that you so much for all of your gifts to the community. I have been interested in cross-platform development since around 1980 and HTML/CSS/JavaScript combo seems like our current “silver bullet” – but only with the help and generosity of people like you.


  56. Thanks alot for this script. I actually needed it for horizontal scrolling, so messed a little around with it and got it working. I haven’t found any bugs yet, but please let me know if you find something.

    Hope it is ok i link to it from here :
    I’ve also made a fast demo page from the original demo page here

    I don’t know if I could have done something wrong about copyright, so i just edited the original file leaving the comments on top. Let me know and i’ll pull it down again.

    Maybe someone can help figure out how to get vertical scroll working for the whole page as it would usually. I’ve put some “hej” text going way down the page on the test page so you can see it won’t scroll. (if you start scrolling above the horizontal scroll it is possible to scroll down a little


  57. I’m kind of a noob at javascript, where would I need to put myScroll.refresh(); in my code. Do i need to put it in with my ajax or some sort of onload in the html that ajax loads?

  58. @Adam, the refresh() needs to be called once the content of the scrolling area changed (at the end of the ajax request just after you changed the innerHTML of the scrolling div).

  59. i am on Iphone os 3.0 and the line that seems to effect the scrolling is
    var theTransform = parseInt(window.getComputedStyle(this.element,null).webkitTransform.split(‘,’)[13]);

    in iphone os 3.0 it seems to return only 5 values. if you change it to 5 it will work however it doesnt seem to be hardware accelerated. Theres still another problem with the myscroll.refresh but i am still looking at that.



  60. @Martin,

    Great that you are looking into it. I only wish they allowed web devs access to the beta. It could be that they just broke something in safari that will get fixed but if not then we need people to fix the problems πŸ˜€

    Also is it me or does moving elements left and right within this scroller lag?

  61. Hi

    Great work πŸ™‚

    Like some others here, I was interested in using iScroll to extend a DashCode web app I’m working on. Here are some tips I have come up with.

    My app accesses an online database of tens of thousands of records in a 3 layer hierarchy. So the DashCode StackView has three subviews that are used to drill down to the subset of interest using AJAX calls to fetch JSON data sets. The selected subset may contain 100’s of records, and that’s where a scrolling list is needed. I quickly found that DashCode lists are really not very efficient once you load more than a few items into them. And they are very unfriendly to iScroll.

    1. ListController.reload() only achieves about 10 rows per second on my G3 iPhone. That’s OK for 10 to 20 items, but if you have hundreds the response is unacceptable, as the List pre-loads all its content, even if there are only a few visible rows. And whenever you update the list you have to reload the entire list again.

    2. DashCode’s use of elements for the rows, with ‘s for each column field, creates way too many tags in the scrolling div. Each 2-column data row is a minimum of 3 tags, and a few hundred tags result in very jerky scroll action, with frequent blank screens as it fails to keep up.

    I didn’t want to throw the entire DashCode framework out (yet), as it does provide a lot of easy-to-use structures. So I have replaced the DashCode List with a home-brew div, created using document.createElement(), made a child of a DashCode Box which is its wrapper, and passed to iScroll to look after events. It is given one child div per column, each styled {white-space:pre; float:left; width:[column_width];line-height:[row_height]} So I only need one tag per column of the table, regardless of the row count.

    I concatenate my AJAX-sourced data into each column with ‘n’ between the values, which puts them on successive rows as a result of the ‘pre’ styling, with no tags to separate rows or cells; and I use the various element sizes and offsets to calculate which cell is hit if I want to handle a click in the table, or to edit it on the fly.

    I have to to change the iScroll.refresh() method to use element.scrollHeight instead of element.clientHeight for some reason, as element.clientHeight always seemed to be equal to the wrapper clientHeight. Also, the wrapper needed {overflow:hidden;} in its CSS. But maybe these are side effects of my own lack of Javascript experience …?

    I hope this helps someone πŸ™‚

  62. Hi

    Thanks for the great work..

    I am using the script to control the scrolling within ‘scroller’ div i am maintaining a playlist and when Load more button is clicked i will show the next 10 playlist.

    I achieved the scrolling smoothly, but one issue i am facing is when i click the load more for the first time the page is getting blacked out and showing. During next time it is ok.

    Is this bcas i am using ajax scripting and it doesnt work in parallel with iscroll?

    your advice /suggestion will be most helpful

    Once again thanks for the great piece of work, its really amazing controlling the native app scrolling with Javascript …Great



  63. You should make sure that your AJAX calls are asynchronous. **

    The basic XMLHttpRequest object can be asked to operate in either mode. Somewhere in your code, or in the library you are using, there will be an open() call to the request object. This takes three parameters – the mode (GET or POST), the url to send the request to, and a boolean that has to be TRUE to start an async request. It that third parameter is FALSE then your whole Javascript, including iScroll, with wait for the server response before continuing.

    Note that iScroll will only scroll to the end of the current data, so you will not be able to scroll beyond that area until the server responds, unless you artificially fill the div with space to be filled when the data is available.

    ** [I was never clear on how an AJAX call could be synchronous, since the first ‘A’ in AJAX stands for ‘asynchronous’, but what do I know!]

  64. Seems you cannot place an iframe within the scrolling area. It appears as a fixed element.

  65. @AlanH
    Thanks. I was finding the same thing but calculated the height and set it myself. I calculate the height of the scroll region, set the clientHeight and then call refresh. That was the only way I could get it to scroll properly.

    I did find that using the stackLayout did not work and abandoned it in favor of the browser example from Apple. It is much cleaner but requires more work for the transitions.

    I am finding that the iScroll script particularly with the alphabetical list is buggy on the device. It works really well in the simulator but runs into issues on my actual device. I have over 400 items in my list and then a large content area. I am sometimes seeing flickering and choppy scrolling on the device.

    I think this script has potential but there are still some issues with speed that I am encountering.

  66. Great article/tutorial, thank you for taking the time to write this down!!!
    I am sure many iPhone devs are finding this very useful.

    I have one issue in regards to CSS background styling. Everything below the wrapper height is not showing any background css images at all. Do you know why this is happening?

    Calling refresh doesn’t do the job.

  67. Hi matteo,

    Thanks for your wondeful script, we used your script for our web app, it works fine in iphone O.S 2X, but this script does not scroll smoothly in iphone os 3.0 (beta version) due to getComputedStyle() which returns a 2d matrix. Is there any alternative for iphone OS 3.0?

    Thanks in advance.

  68. Hi Matteo Spinelli,
    i am a beginner for javascript . The solution explained for the problem mentined by Mr. felka is not clear to me.

    Although It make a mouse event by document.createEvent and dispatchEvent, the event works wee. But the display is incorrect.

    for example:

    ……(total 100) …

    if you click on each checkbox, the status of checked is correct but display may not. It display correctly in nth checkbox (show in first display) but it display incorrectly after nth checkbox(not show in first display). This may be the bug of safari

    could you explain with the codings

  69. Quick question, I have a setup right now where the middle div is scrollable, and there’s a static div at the bottom that contains a drop down list, where if you change the selection, it will go to a different page. When you go to select from the drop down list, it pushes the entire webpage up, making half of it unviewable. I’m curious to know if there’s a javascript event trigger for when the user presses “Done” or something to that effect. Cheers

  70. Nevermind my previous comment, I got it to work with an onblur call, my bad

  71. I’m trying to put a drop down selector form inside the scroll area and it does not work. It’s not selectable inside iPod/ iPhone Safari. Has anybody tried this? Has anybody tried using this on the iPhone 3.0 beta build? Thanks.

  72. I also have the background-issue; all items below the initial overflow – all items to scroll to – having their own background-color or background-image look fine, except the background is not shown. I’d be happy to provide a fix for this, if I would have a clue about what’s going on!

  73. Hi !

    I had the same bug with the select. I’ve trie this

    But it doesn’t work I start looking and I found a solution that seems to work fine ! It’s just a little change at begining of the code:

    handleEvent: function(e) {

    var theTarget =;
    return false
    switch(e.type) {
    case ‘touchstart’: this.onTouchStart(e); break;
    case ‘touchmove’: this.onTouchMove(e); break;
    case ‘touchend’: this.onTouchEnd(e); break;
    case ‘webkitTransitionEnd’: this.onTransitionEnd(e); break;

    I hope it could help some of you


  74. The script has been finally updated for OS3.0 compatibility. It seems to work flawlessly but extra code is needed to disable the new cut-n-paste functionality.

  75. Hey great work on the iScroll, just one question, i notice when i scroll and let off the screen flashes black just for a moment, its not that big of a deal on something small but I have it implemented on a long list and it can get to be very irritating. I have the code used just as implemented in your examples. Any advice or help would be greatly appreciated.

  76. > It seems to work flawlessly but extra code is needed to disable the new cut-n-paste functionality.

    Nail meet sledgehammer:

    -webkit-user-select: none;

  77. I noticed the screen flash too. It seems to happen when the list is very long. Anyone have a fix for this?

  78. Also, to speak more to the screen flashing issue, it only happens when for the iPhone 3.0 SDK

  79. Hey nice work !
    I just noticed there is a weird behavior when it comes with a form and input text…
    the viewport is then scrolled so that both header & footer are not replaced correctly.
    Is there anything to improve that ?

  80. Very good work! I would like to use it for an index page with a list of thumbnail images and links to detail pages. But I need also to enter into the list with named anchors, one for each list element. It works, goes to the proper anchor but does not allow to scroll back to the div top, as if the div started at the anchor. Any suggestion?


  81. Hey Matteo,
    Very nice work. I implemented this in my code and works well except for one little detail. When I scroll down the scrollable area, as soon as I lift my finger it comes back to the top again instead of showing where I left of scrolling. Any idea how I can fix this? My scrollable region has a rounded corner list.



  82. Hi, Matt. Very useful work. Everything was perfect until iPhone 3.0 introduced a regression that loses hardware acceleration and makes the entire screen go black every now and then.

    I filed a bug with Apple. Here’s my writeup:

    Here’s Apple’s response:
    This is a known issue. The workaround is to assign a 3d transform to the elements being transitioned:
    -webkit-transform: translate3d(0, 200px, 0);
    We consider this issue closed. If you have any questions or concern regarding this issue, please update your report directly (

    I’m not entirely sure how to go about implementing that. Suggestions, anyone?

  83. @Briz: Holy javascript, Batman! It really works! Translate3d kicks ass πŸ™‚ Gonna update all the scripts asap. Thank you man.

    update: all the scripts updated! go get’em

  84. @Matt: Holy awesome, Batman. This is why I love the Internet. I don’t so much love the fact that the bug is known, Apple isn’t going to fix it, but it is kind of cool that the fix is literally a few characters.

    Thanks again.

  85. I tried this code with new Palm SDK emulator and Android (sdk-windows-1.5_r1) emulator. Unfortunately id does not work to me. I failed to bind event listener to ‘scroller’ div. BTW, on Palm emulator I failed to bind listener (to get a call of the listener) even for document.body.
    Did anybody have such experience?

  86. Hi Matteo,

    this script is great! It works well with datalists, but I’ve encountered a problem when using it with a project that contains Dashcode 3.0 datasources. It is a very strange behavior that regular datalists scroll appropriately, but if a datalist is bounded to a datasource, it doesn’t recognize the height of the datalist…. Any help appreciated and Thanks again.

  87. Hi Matteo,

    Fantastic script. I have a problem now that I’m targeting that seemed to appear since I targeted iPhone Os 3.0.1, although may have nothing to do wit that. Anyway it was working great before but now the scroller content jumps back to the top when I release. Seems like the same problem as comment #96.

    Any ideas why, have you tested it with os 3.0.1?

  88. @deafmetal and all: sorry guys did not tested the script on 3.0.1 yet. It’s very frustrating when a little update such as 3.0.x breaks the code, it seems that Apple doesn’t want use to use javascript but just native code. Anyway I’ll try 3.0.1 today.

    @gab cas: dashcode is a pain in the arse… really πŸ™‚ try to avoid using it if possible. btw, your problem seems related to the fact that iscroll checks the elements height before the ajax call loads async data. Have you tried calling the iscroll refresh method as call back function on-ajax-complete?

  89. Hi Matteo,

    I am running into the same issue as @deafmetal (#104), is there any update on what’s going on?


  90. @matteo, @deafmetal, @divurr Don’t use FLOATS. When you do, in the refresh function this.element.offsetHeight becomes zero, which makes maxScroll 0 so that scrollto goes to the top of the page.

    Also, the SELECT input issue.

    Find the onTouchStart function and make it look like

    onTouchStart: function(e) {
    if( != ‘SELECT’) e.preventDefault();

  91. The FORM input text can be cleaned up by “refreshing” the textbox onkeyup. One hacky way of doing this is to toggle the background color from white to transparent on each keyup. Obviously other(better) variations on this workaround exist.

  92. Anyone been able to get the form input with garbled text bug fixed? I tried a few things – including that cryptic clue from #108. I ended up fixing it on desktop by blur/focus – but this breaks on the iPhone (iPhone doesn’t focus back!).

    I will offer money if this will get things fixed, please contact me at, desperately want to get this bug fixed!!!

  93. Does anybody have got the current version working on Android. Are there still changes needed to make it working there? Any help is really appreciated.

  94. It seems that Android do not yet support 3d transforms. Using translateY on Android works fine!

  95. Has horizontal scrolling been added yet?
    This is exactly what I need except horizontal

  96. I was able to fix the “cryptic text box” issue by using absolute positioning instead of webkitTransform and translate3d.

    The presence of ANY webkitTransform causes the text boxes to become garbled, and there seems to be no way to “undo” the transform (e.g.: setting webkitTransform to empty string leaves the text boxes garbled).

    Instead, if I have a text box, I use absolute positioning instead. I modified the constructor to set this up and also modified the position setter to set instead; went as far as modifying the constructor to check for any text or password inputs and switch to absolute-position mode.

    The scrolling is a bit choppier this way, but at least the rendering isn’t screwed up.

  97. Hi
    First thanks for the great word you’ve done.
    I’m trying to insert iscroll in my iUI webapp. It works great in the first page but I don’t find where to put the refresh() call in the other file.
    Is there anyone who can help me for my issue??

  98. nice πŸ˜‰ first: sorry for my bad english πŸ˜‰
    but you must refres the scroller-height, when touched the screen! if loading a content with ajax into scroller changes this the height of scroller. i refresh the max height of scroller when i touched the screen – thats works πŸ˜‰


    onTouchStart: function(e) {
    if( this.element.offsetHeight<this.element.parentNode.clientHeight )
    this.maxScroll = 0;
    this.maxScroll = this.element.parentNode.clientHeight – this.element.offsetHeight;

  99. Am using this to build a tab – bar, and i have changed the ‘300ms’ to ‘600ms’ after comparing it with other bouncy content apps, 300 is way to fast πŸ™‚

  100. Great script, only problem is that it kills my orientchange event. Anyone else experiencing this?

  101. Could you please look into how to make this work with NimbleKit?
    I have tried, but didn’t succeed.

  102. Great script. One issue that I’m having… to enable scrolling for a div, I have to touch and hold the element for about 300 ms, then it can scroll. For some reason, there is a small delay before the initial touchmove event is detected. Is this an issue for anyone else?

  103. Matteo,
    How bad is the performance with the scrollbar? Do you mind releasing the code so I can try it or will that be a 3.0 feature.

  104. I would really like someone to help me out with making a horizontal scrolling div. I see a lot of people have asked for it above and one person posted heir links but they appear to be broken links now.

    Can any moder person help me out??

    Thanks in advance,


  105. Hi,

    Please tel me is the scroll script works for an edge-to-edge List.


  106. So it isn’t beautiful yet, but I added scroll bar support that simulates the iphone native scroll bar. All my tests thus far show no slowdown.

    Please contact me Matteo if you would like to update your script for everyone to include it.

    In an effort not to make it too heavy the only thing I don’t simulate is maintaining opacity during the translation. My scroll bar will fade in when you touch the screen and stay visible only until you stop touching.

  107. @Adam, the script will be both hor/ver

    @Agustin, yes, why not?

    @Weston, I am rewriting the script from scratch, I’m afraid your scroll bars would not work anymore, but please send your script to me (matteo at this domain) I’ll be glad to adapt your code to the new scroller.

  108. @Matt, I noticed you said you are rewriting the script… do you have a timeframe for completion? I’m trying to decide if I should implement what you currently have or wait for the new one!

  109. @Matteo, Interested in the rewrite as well. Do you have a release date in mind? Thank you for focusing on project.

  110. Hey Matteo,

    I figured out how to make links work properly in iScroll, so you can hold them down to open in new windows, etc.

    Instead of dispatching your own click event on touchEnd, just capture it and conditionally let it through depending on whether the scroll has moved or not.

    I’ll send you an e-mail with a patch you can use if you’re interested.

    Robert Estelle

  111. Is it just me, or does the latest mobile safari (firmware version 3.1.2) break support for javascript 1.5 getters and setters?

    Just spent a bunch of time trying to get this to work on my hardware (on the simulator it was fine), and some logs revealed that it wasn’t getting into the `set position(pos)` function at all. I refactored iScroll to use a function (set_position: function(pos)), and everything was just dandy.

  112. @Sam: I have firmware 3.1.2 and it still works for me. Anyway I’m busy working on a new version with XY scrolling and preloading which does not use getter/setter. It should be ready in a couple of days.

  113. Cool, it would be sweet if you threw it onto github as a gist, or some other sort of source management, so that people (me) could throw up patches against it. Seems like some other people here would appreciate that too.

  114. Hi. Love the script. Did the issue of the content bouncing back to the top after releasing the finger get addressed? See #96 and #104 above. That’s my only real issue.



  115. @John (and others): please can you send me a video of this issue? I really can’t replicate it. Also please provide details about your hardware.

    @Sam Cole: I’ll be glad to publish it on googlecode (I’d like to use mercurial, though). I’m also planning to create a whole native framework, but we’ll talk about it later πŸ™‚

  116. Glad to see this script and it is of great help for me. But I wonder if you could update this script to make it move left or right?
    I don’t know too much of JS and CSS so it would be nice if you could do the update or guide me do the udpate

    Thank you~ looking forward to your reply~

  117. Thanks for your prompt reply~ And when will the new release come out? this feature is very important for my project.
    Thanks for your great work and the ‘scrolling’ feels really GOOD

  118. I think I get it now. If you “scroll” down (swipe finger up) beyond the height of the div being wrapped, it “bounced” back to let the bottom of the div settle at the bottom of the wrapper. It just gives an odd appearance at first.

    I may look into ways to disable the scroll effect when the text is smaller than the wrapper (no need to scroll).

    sneak preview of the new iScroll πŸ˜‰ 360 degrees scrolling + scrollbars (vertical bar only in this video). A lot of work and optimization to be done yet. A new feature not visible in this video is the preloading phase which prevents a lot of flickering especially when you have pictures in the scrolling area.

    @John: I’ll work on that issue as soon as the new scroller will be ready. In the worst case we’ll have to add a timer which checks the scroller position. Hope to be able to avoid it, everytime I use a timer I feel dirty inside πŸ™‚

  120. I’ve watched the movie of the XY scrolling, really COOL. May I get the latest code to test in my project?

    And by the way, I hope the scroll bar is an option (cause I don’t need it in my project)

    Can’t wait, could you please share your code (it would be great and appreciated if you put it on github or googlecode)

  121. @Matteo: The new iScroll looks great. When will it be ready?

    When I build a native iPhone app with 3.0+, and provision on a device (not simulator), I have to hold down for half a second then swipe to activate the scrolling div. A delay is present. Is there a fix for scrolling on iPhone 3.0+? Btw, 2.2 works great on the device, just not 3.0+.

Comments are closed.