Scrolling div for mobile webkit turns 3

I’m pleased that my original iScroll was useful to many. In the past months I received dozens emails asking for new features and bug fixes. I think it’s time to start developing a new version of the scrolling div for mobile webkit with added functionalities.

I recently modified the structure of the blog to have easier access to my projects. The iScroll has now a dedicated page, please head to the iScroll project page to get the lastest updates.

I’ve been asked to publish a new version of iScroll even if in development phase. Here you have it, but keep in mind that we are in Alpha1, the script is very rough and not ready for production. Okay, we are finally out of alpha and I’m moderately proud to introduce Beta phase. Please consider that I’m now working on GhostTouch, a framework dedicated and optimized to touch enabled mobile devices. The iScroll is a stand alone version of the scroller I’m developing for GhostTouch.

First things first. iScroll was born because mobile webkit (iPhone and iPod touch mainly, but also Android and Pre) does not provide a native way to scroll inside a fixed dimensions overflow:scroll|hidden|auto element. This unfortunate situation prevents any web-app to have a fixed header and/or footer and a scrolling central area.

Luckily mobile webkit offers a powerful set of hardware accelerated css properties that can be used to simulate the missing functionality, so the iScroll development has started… But there’s no rose without thorn. Making the scroll feel native has proven more difficult than expected. Version 2.x of the script was good enough, but it was lacking a lot of features.

Enough blabbing. Have a look at the screencast I baked for you or point your mobile device to

Update 2010/05/06 – 3.1 beta 1: The most requested feature has been finally added. When new content is added or removed from the scrolling area (eg: ajax calls) iScroll automatically sets the correct position to comfortably host the new contents. We are still in beta, please give feedback.

How to use

All you need to do is to initialize iScroll with something like: myScroll = new iScroll('id');, where id is the #id of the element that will be scrolled. You can place it on window.onload or document.DOMContentLoaded.

iScroll automatically detects if you need vertical, horizontal or both scrollbars, but you can force scrollbars hiding with the optional second parameter. Eg: myScroll = new iScroll('id', {vScrollBar: false, hScrollBar: false}); (this prevents both scrollbars to appear).

On orientation change iScroll also refreshes itself and detects if the scrolling area has changed in size. You should add your code to resize the elements on orientationChange as shown in the example.

Other considerations

I decided to remove the scrollbar shrinking effect (ie: when you scroll outside of the screen the scrollbars reduce in size). Can be done with little effort and some frameworks already implement it, but it’s an inconsiderate waste of resources –precious resources– for such a small feature.

The script should now work on Android, too (at least on version 2.1, please give feedback).

The momentum formula I’m using feels pretty natural, I use a completely rewritten (and ridiculously simple) algorithm. If deceleration doesn’t look natural to you, you can try to tweak friction and deceleration parameters on line 273 and 274.
Q: Why aren’t you adding feature X?
A: I’d like the script to work on older devices. Not everyone has a SnapDragon 😉 Plus, I’d like to keep this script as bare bone as possible so it’s easier for you to customize it to your needs.

Q: I’ve developed feature X, may I send it to you? Will you add my code to your script?
A: Please do! It’s not guaranteed that I will add your feature to the script, but I’ll review all code you send to me (matteo [at] this domain). Consider that scripts will be released under MIT license, if this is a no-go for you, don’t send.

Q: I’m in a hurry and I need feature X to be added to your script ASAP. Can you help me?
A: Have you considered hiring me? (matteo [at] this domain)

Go to iScroll project page

186 thoughts on “Scrolling div for mobile webkit turns 3”

  1. I too noticed performance problems with scrollbar shrinking when I implemented my own scrollbar for iScroll 2.3. Moving is no problem because transforms are hardware accelerated, but changing the height of the scrollbar make the performance awful.

    I ended up with placing the scrollbar in a div with overflow set to hidden. That means you could just use transforms to move the scrollbar partially outside of the visible area of the div and effectively shrinking the height of the scrollbar.

    The only thing is that the scrollbar is rounded and the div is rectangular. So if you ‘shrink’ the scrollbar one side will be rectangular and the other side will be rounded. I solved this by placing little dots in the background color on top of the div in all four corners. This makes it look rounded, but it is a bit fragile, especially if you want do not have a solid background color. Still it works pretty good in my own app.



  2. @Niels: I think the best thing we can do to shrink the scrollbars is by using -webkit-transform:scaleY(). Should work but probably rounded corners will be squashed. Not tried yet, but should work pretty well.

  3. @Matteo: Yes, I thought about that too and can see no real performance problems. In my own application I opted for the ‘dots’, simply because I wanted to have ‘real’ rounded corners and my background color is pretty stable. But for a more stable solution I would try scaleY instead.

  4. I’m curious how one might go about using scrolling with multiple divs using iscroll.js. I’ve played around with it a little using 2.3 and haven’t had any luck so far, but I feel like I’m missing something pretty simple.

    For example, in a PhoneGap app I’m working on, I’ve got an absolute-positioned div that slides into visibility from the left when the user taps an item in the original scrolling div. If I wanted to scroll the second div, how would I go about doing so?

  5. Personally I wouldn’t create new instances of iscroll. I would have it so all diva with an iscroll class could be scrolled. You wouldn’t need to initialize it more than once, only refresh it ontouchstart of a new element.

    As for the scrollbars, you should have a parent element that is 2px smaller than the scrolling div on the top and the bottom and then give it overflow hidden and a radius on the corners. When the scrollbar goes out of the boundaries, it will appear to get shorter and not just get cut off with a flat edge. Then you would only need to edit the height of the scrollbar when it refreshes and you can limit how far it can go out of the boundaries so that it doesn’t go more than a circle. If you wanted to be really exact you could even add a little White go around the scrollbar and have add one to the far end of the overflow container when it goes out of bounds.

    Also, you should add a zoom effect that allows you to zoom in on whatever is in the scrolling div using pinch gestures.

  6. hi Aresinferno, thanks for your feedback. I’d like to test the scale transition first. It sounds more logical and doesn’t need additional markup. The rounded container is a brilliant idea, though.
    Regarding the zoom, I don’t think it will be implemented, not in the core version at least. Maybe I could add some plugin system. I’d like to release even the scrollbars as a plugin.

  7. Thank you for this slick piece of code.

    Works great, easy to implement. I’m actually using it inside a PhoneGap App.

    Horizontal bouncing is the only “bug” visible for me, and isn’t an issue.

    Thanks again!

  8. Great script however i ran into an issue when i placed a tag in it. It seems to float over everything and ignore the scrolling. Any ideas?

  9. Alpha3 is out, now you can turn on/off scrollbars individually.

    // Horizontal scrollbar only (vertical is disabled)
    myScroll = new iScroll(document.getElementById('scroller'), 'x');
    // Vertical scrollbar only (horizontal is disabled)
    myScroll = new iScroll(document.getElementById('scroller'), 'y');
    // Scrollbars disabled
    myScroll = new iScroll(document.getElementById('scroller'), 'none');
  10. @Aresinferno, A parent element with rounded corners and overflow hidden will not work. The child element will still clip using a rectangle and not take the rounded corners of the parent into account. It’s a bug in Webkit.

  11. @Niels,

    Seriously? And I thought webkit was the king and it can’t even get something as obvious as this correct. There must be some kind of suitable solution.

  12. The drop down problem still exist in this version, I suggest adding the following code at the beginning of handleEvent:
    var theTarget =;
    if (theTarget !== null && theTarget.tagName === ‘SELECT’) {
    return false;

  13. man, you’re good.

    but, lets say you need only veritcal scrolling. it seems easier to track a Y-axis swipe, and use a CSS animation with a default distance and ease-out. Boy, its crazy that position:fixed isn’t properly supported.

  14. @timtim: you mean no acceleration? Just a default distance? Unfortunately it wouldn’t feel natural (already tried 🙂 ).

    I agree that it’s crazy the amount of JS needed to do such a simple task. If Apple can’t make position:fixed work at least they could introduce a CSS property like: -webkit-scroll: x|y|auto|none

  15. I uploaded a new version of the script which supports the scrollbars shrinking. It’s still buggy but it works, I’ll debug it in the coming days. Unfortunately, as noted by another user, round corners do not clip the webkit-transition. I also tried with webkit-mask property with no success. Scaling the scrollbars would have been perfect, but there’s no way not to have the round corners to squash. So a lot of hackery is needed to shrink the scrollbars.
    The solution is to move the scrollbar outside of a overflow:hidden container and recreate the rounded corners with an overlaying small rectangle. A pain in the butt, let me say it! And still not perfect. Any other ideas?

  16. @Matteo How about splitting the scrollbar into three parts. First a div with half a circle. Then a div for the body of the scrollba. Finally again a div with half a circle. To change the size would be relatively simple. To move the rounded corners you can use a translate transform. To change the height of the body you could use a scale transform. And the best thing is everything should still be hardware accelerated.

  17. @Niels: it’s not easy to have the scaling body to match the translating corner (you know floats rounding is not our friend). But maybe I found another way using background images. I’ll test it later. Today I also played with a similar code by Apple and I’m pleased to see that their implementation has more bugs than mine 😛

  18. @Aresinferno: that is the code by Apple I was playing with. But it has many issues (consider that iScroll3 is alpha stage) and lacks some functionality but most important it’s not MIT licensed, you can’t actually use it 😉

  19. @Matteo But that won’t stop people picking it apart or even some using it.

  20. Scrolling on iphone 3g is pretty choppy with PastryKit.. Don’t know if it’s the case with iscroll for the same content..

  21. I created this last night in 2 hours:

    Matteo – Your code helped me out way back months ago, and I posted way back, having fixed the stall that happens when dragging off the bottom of the touch screen..

    I didn’t even know pastrykit existed until after I made this scrolling demo.

  22. Matteo, does your newest version address the issue with text input pushing the footer div up the page, requiring the user to tap the status bar to scroll everything back into view?

    That’s the only thing keeping this from being a killer script (oh who am I kidding, it’s already pretty killer!)

    Great job so far!

  23. I saw you had code commented out at the bottom of onTouchMove for launching the touch end event.
    That code is very similar to the fix I created for swiping off the bottom of the screen. I created this for v2 of iscroll, but I have updated it for iscroll v3.

    “Prevent the scrolling to lock when swiping outside of the screen”:
    within iScroll (el, scrollbars), I put this:

    this.element.iScroll = this;	// Let DOM have access to the iScroll object

    after this.element = typeof ….

    at the bottom of onTouchMove, there is a need to introduce timers again (sorry!) but it does what is needed (please note, the value-check on startY is to handle very-fast swipes whose last onTouchMove event was not close to the bottom of the screen):

    // Fix for touch-move off bottom of screen not firing touchend event
    if (typeof(this.stopScrollTimeout) != "undefined") {
    orient = Math.abs(window.orientation);
    if ( (orient == 90 &&  this.startY > 90) || (orient != 90 &&  this.startY > 250) ){
    	this.stopScrollTimeout = setTimeout( function() { t=e.targetTouches[0].target; t=(t.nodeType==3?t.parentNode:t);t.iScroll.checkOutOfBounds(e);}, 300);

    Between onTouchMove and onTouchEnd, I placed this function (note, I replaced my code for the function with a duplication of your code from the bottom of the onTouchMove, to prevent confusion):

    checkOutOfBounds: function(e) {
    	var theEvent = document.createEvent("TouchEvent");
    	theEvent.initEvent('touchend', true, true);
    	return false;

    Hope that helps.

  24. I’ve designed a carousel for a webapp game. How would I go about “locking” an axis meaning if i just want it to scroll left and right and not have it dragged up or down (Y-axis) is there a way to do this. I can’t for the life of me figure out how to prevent this in the code.

    thanks in advanced!


  25. okay perhaps i’ve spoked too soon. to achieve the desired effect i spoke about (locking an axis so that it doesn’t move if those bounds aren’t specified) replace = ‘translate3d(‘ + this._xPos + ‘px, ‘ + this._yPos + ‘px, 0)’;


    if(this.scrollbars.x && this.scrollbars.y) { = ‘translate3d(‘ + this._xPos + ‘px, ‘ + this._yPos + ‘px, 0)’;}
    if(typeof(this.scrollbars.x) == ‘object’ && typeof(this.scrollbars.y) == ‘undefined’){ = ‘translate3d(‘ + this._xPos + ‘px, 0px, 0)’;}
    if(this.scrollbars.x == ‘undefined’ && this.scrollbars.y){ = ‘translate3d(0px, ‘ + this._yPos + ‘px, 0)’;}

    im sure theres a better way of going about this, but this simply just works.

  26. oop, paste this instead:

    if(typeof(this.scrollbars.x) == ‘object’ && typeof(this.scrollbars.y) == ‘object’) { = ‘translate3d(‘ + this._xPos + ‘px, ‘ + this._yPos + ‘px, 0)’;}
    if(typeof(this.scrollbars.x) == ‘object’ && typeof(this.scrollbars.y) == ‘undefined’){ = ‘translate3d(‘ + this._xPos + ‘px, 0px, 0)’;}
    if(typeof(this.scrollbars.x) == ‘undefined’ && typeof(this.scrollbars.y) == ‘object’){ = ‘translate3d(0px, ‘ + this._yPos + ‘px, 0)’;}

  27. Is there a way to save the last scroll position so that when the page is refreshed it can position to its previous point?

  28. Awesome, awesome script!
    I have seen others, but they do not do the job as well or as neatly.

    Is it possible to limit scrolling to just one axis?

    FYI, iScroll is compatible with “Overscroll” ( )
    If you call overscroll on the wrapper, then PC users can scroll the DIV with a click and drag motion too.

    This enables iScroll content to be fully cross browser and behave similarly.

    I have a demo here:

    iScroll is used for the main menu and if you click help in the main menu, the help page is an iScroll too.

    This is tested on:
    Desktop Firefox
    iPhone Safari (Normal)
    iPhone Safari (“Homescreen App” mode)
    Desktop Safari
    It should look identical* in all. It handles any screen resolution and also change of dimensions (rotate on mobile, resize on desktop) in all.
    (* In desktop browsers, in the help menu, the scroll bar is shown deliberately, I prefer it that way)

    Just onhe thing – in the help menu iScroll, why is there no styled scrollbar like there is on the main menu iScroll?

  29. Hi.

    Thank you for this. 🙂

    Quick question…I started a website, in the overview of the apps, i have an iframe. i used your code so it’ll port well on the iPhone. However, i can’t seem to make it work.

    I added the and around the lines in my html (not in the html that the iframe gets its content from). I also added:

    to the head of that same html file. Added the js file, too.

    I don’t know what i’m doing wrong…hope someone can help me with this.

    If any angel wants to help me with this, please email me at: lauranoel at me dot com, so i can send my code. 🙂

    Thanks in advance!! 🙂

  30. I finally got it to work on the iPhone. Problem now is the iFrame on safari isn’t moving. When i use it on my iPhone, the iframe scrolls perfectly.

    this is my html:

    Your browser does not support iframes.

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

    this is my css:
    div#wrapper {
    clear: both;
    height: 297px;
    width: 421px;
    margin-top: 214px;
    margin-left: 333px;
    position: absolute;
    z-index: 5;

    div#scroller {
    clear: both;
    height: 297px;
    width: 421px;
    margin-top: auto;
    margin-left: auto;
    position: absolute;
    z-index: 4;

    hope someone can help me figure out why it isn’t working on safari anymore.

    Thanks in advance!! 🙂

  31. hi matteo

    referring to:


    i still have the problem above, how can i change the top attribute instead of -webkit-transform element on screen?

    i tried: = ‘translate3d(0, ‘ + this._yPos + ‘px, 0)’;

    but simply this obviously doesn`t work. unfortunately i can´t find a solution. could you plaese show me yours?

    thanks a lot

  32. Hi,

    I have an intranet version running iWebKit and it works well… I run it in fullscreen mode
    but when adding the iScroll all of my links are opened in safari instead of keeping the new url in fullscreen mode.

    What am I doing wrong?


  33. Has anyone been able to get this to work correctly on Android? I just tried it on the Nexus One, and it works, but only for the first scroll gesture. After that, webkit goes back to scrolling the entire page again.

    I’m hoping its a simple fix! Please let me know if you have any ideas.

  34. I am using iscroll for a iphone-like application using as the framework.
    Well, I’m running across an issue that I hope I can get help with.
    I am running iscroll in the third page of my application, that means that the div that has the iscroll is not the div in display when the application is being loaded. I have set a delay of 3 seconds to give iscroll enough time to load after all the other elements of the applications are being loaded but iscroll is still not responsive.
    Iscroll is only working when I refresh the application when the div that contains iscroll is displayed on the iphone.
    Does anybody have any suggestions in how to get iscroll to respond, or be ‘active’ for a lack of a better term even when the div that contains it is not being displayed at loading time?

  35. Awesome script!
    yah im one of those people who only post when there’s a problem..
    last night, I was marking up some manual image crops in an iscroll with a few individual spans (( display:block, overflow: hidden )) and just needed to put them in line.
    Of course I then just floated them all to the left. Looks perfect.. S#!& , displays fine with floats but the iscroll height is off , 0 height? after scrolling down it pops right back to the top like there is no content ..
    Tried a few things to adjust the height, fixed positioning elements further down , no results.. the floats seem to be offsetting something.
    For about 30 minutes or so I tried every other side by side technique I could think of including just throwing everything in the old table schema , tables display fine (( but oddly enough there seems to be a mobile safari bug where images intermittently are hidden untill touched when in a td .. ))
    so damn .. no floats, no tables, can’t use display:inline, will kill the crop effect , ok display:inline-block seemed to do the trick.
    I double check it this morning to and it seems fine.. 90% of the time .. now randomly ( say 1 out of 10 times ), when the iscroll is initiated.. it starts midway through the content, the first line of spans are hidden unless you scroll Up..
    If anyone has dealt with this scenario, feel free to school me.
    and Matteo, again awesome script, sorry my first post is about an issue..

  36. false alarm,
    I swapped the spans with divs , corrected the mid-scroll issue.
    although.. then the images seemed to load whereever they wanted and not inline.
    for test, i threw some color on the div backgrounds to check positioning and they load perfect before the images arrive.
    this prolly has more to do with mobile safari than with iscroll im sure.
    considering the divs load in correct position, I just applied the images individually to the div background .
    floating inline image crop effect successful.
    just another css nightmare.. on to the next one

  37. I’ve been using an older version of this script & as reported by other users I too have come across the issue where the text in input boxes gets garbled.
    Has this issue been resolved in the latest version?

  38. Thanks for this, it’s let me develop a good fixed layout for the iPhone. It’s broken on an Android simulator for me, still looking into that.

    The site I’m working on is meant for many phones, it uses Javascript to make links load dynamically. This functionality broke when I added iScroll; I fixed it by changing the final argument to the initEvent call in the onTouchEnd method to true, allowing the click event to be canceled. Any reason it shouldn’t be cancelable?

  39. Here’s how we were able to fix the Android problem (only the first event would scroll):

    In onTouchEnd function, comment out this line:
    //document.removeEventListener(‘touchend’, this, true);

    Anyone had luck with the following?

    -preventing horizontal scrolling on elements that aren’t wider than parent (it is a To Do on the creator’s list)
    -clicking links that are within the iScroll region:
    specifically, I’m trying to set up a rule in onTouchEnd function that if the move was fewer than N number of pixels set this.moved to false so the click is handled. A) Is this a good approach and B) if not, what would be a good solution to filter “unintended scrolls” so links are available?

  40. @Jason:
    // Vertical scrollbar only (horizontal is disabled)
    myScroll = new iScroll(document.getElementById(‘scroller’), ‘y’);

    reguarding the other issues I’m a bit busy at the moment, but I’ll be back on iScroll next week. So stick around!

  41. is there an easy way to stop the scrolling to the right and left at the moment?

  42. This is exactly what I was looking for to start developing for the iPad – I do have one request. I would like to have the ability to lock the x dimension entirely. I like your implementation of the scroll bars in your last release; however, as I’m scrolling vertically, I’m also pushing the content slightly to the left or right, revealing the gray background on the sides. I want to completely lock down any horizontal movement. (or vertical for that matter if I’m in a horizontal scroll need).

    I will dig into the code tonight a bit to see if there is an easy fix but I thought that I would put this out here as a feature request for future versions – great job


  43. Debugging
    I tried loading this in safari and change the user mode to mobile 3.1.2 to see if I can get to work on my machine; however, I get no movement on the screen. How are doing any debugging work with this script? really missing firebug about now


  44. Awesome script, Matteo, but I’ve noticed one thing:

    The HTML ‘select’ form item doesn’t work when it’s inserted into the scroller div. It displays as you’d expect (first item shown in a box with an arrow to the right, the standard styling), but it doesn’t register any touch events. To make sure it wasn’t my HTML that was at fault, I copied all the code from inside the scroller div into a new page and it was fine. I added the meta tags (no scaling, device-width, web-app-capable, etc) one by one and it still worked okay – so I can only conclude that iscroll.js is causing the problem.

    Tested it with both v.2 and v.3 of the scroller script. Radio buttons are okay, as are checkboxes and textfields.

    Any ideas about how to get select form items working would be great 🙂

    Sorry to only comment when I noticed a problem! Despite this, though, it’s still an outstanding acheivement, excellent work.


  45. Luke, see Comment
    Date: 2009/12/07 @ 19:19
    By: Udi

    Fixed it for me (manually edit iscroll.x.x.js, I’m using 3.0a and adding those four lines fixed it.

  46. Outstanding, Matteo!
    Now there is a small problem with two or more scrollable divs at once:
    The scrollbars will allways show on the last scroller, all of them..
    Your muitiscroll example shows this problem also..

    Is there an easy fix?

  47. hi there, im stuck trying to stop it from scrolling left and right, any help would be perfect…!

  48. Textboxes inside the scroll area get kinda garbled when you type in them. Any idea why?

  49. Okay guys, sorry for all the not replied questions. I’m assiduously working on an uber optimized framework for mobile devices. Follow me on twitter for updates ( The iScroll will be of course part of whole project. I think that there’s nothing like what I’m going to release, and all will be MIT licensed. Stick around.

  50. There is one small issue with instantiating multiple of these per page (i.e. for use with jqtouch). To fix the scoping issue, the scrollbars definition needs to be moved from the prototype section to the main iScroll function.

    function iScroll (el, scrollbars) {
    this.element = typeof el == ‘object’ ? el : document.getElementById(el);
    this.wrapper = this.element.parentNode;
    >> this.scrollbars = {};

    iScroll.prototype = {
    _xPos: 0,
    _yPos: 0,
    scrollX: false,
    scrollY: false,
    maxScrollX: 0,
    maxScrollY: 0,
    << //scrollbars: {},

  51. Has anyone tried to add a Youtube video via object tag or video/audio tag. It seems not to work and float on top of everything.

  52. Thanks for giving us this wonderful function.
    Regarding drop-down select boxes. I applied the solution mentioned in comment #19 and, while the drop-down worked, scrolling failed. I can get the page to scroll OR have drop-downs but not both.

    I placed the suggested code after handleEvent: function(e) and in various other places but with the same result. I see that others have got past this problem, can anyone tell me where I am going wrong.

    I am current;y using Version 2.3


  53. Addendum…

    After looking through the article for the original version I found a comment from Dave (#107) which has cured the problem.
    I don’t know if this fix is specific to Version 2.3 but it worked for me.

    Make the first line after ‘onTouchStart: function(e) {‘ read as follows…
    if( != ‘SELECT’) e.preventDefault();

    That’s all it needs.

  54. ..
    I’ve been loading data into an iscroll div with jquery to prevent from having 100 iscrolls.. and I just noticed that when you load new data it’s at the same scroll position as before even though all the markup in the div is new..
    This would be ok but the problem is that is you’ve scrolled to the bottom , and then loaded new data with less height.. it’s completely blank and you can’t scroll back up ..
    I’ve tried everything I could think of to scroll back to the top when loading new data but to no avail .
    Any suggestions?

  55. nm,
    can add as many divs within the iscroll as needed, so can just swap displays on the divs within the iscroll div if heights are off

  56. Hello,

    is that a bug? i want to load more content in the iscroll but i can’t scroll to the end because the iscroll isn’t grow.

  57. @Bartman
    I wasn’t having trouble with what you’re describing.

    the div you’re using is probably hardcoded height,
    add another innermost div to the iscroll that does not have height attribute and load or append your data to That div instead.

  58. Thanks for such a great tool. I am wondering if anyone has solved the problem I’m currently having. I’m trying to build a little page that mimics the demo but only with horizontal scrolling. Once the user would scroll all the way to the end I have an ajax call to populate the “scroller” div with the next batch of data. The problem is with resizing the “scroller” div once I’ve added the new data. I figure that I need to reinitialize the iScroll for the change in width to take effect. Played around a bit but I haven’t found a solution to this that didn’t cause the page to break. Does anyone have an idea on how to do this or point me in a direction?

  59. @Chris: thats was my problem to. refresh(); Now the iScroll works with Ajax 🙂

  60. @dan: Did you find a solution for locking horizontal/vertical movement? This is a big issue with the new version I think..

  61. Hi I’m very impressed by your job,

    although I have a few problems. Let me explain: I’m using Jqtouch and only the javascript and css in the index.html works. In my case I would like to create another html linked to the index.html. But when I do that the iscroll does fixe the tab bar but I can’t move mt text anymore. Would you have an idea why?

  62. Ahead, here is how you can fix it:

    –               var leftDelta = e.targetTouches[0].clientX – this.startX;
    –               var topDelta = e.targetTouches[0].clientY – this.startY;
    +               var leftDelta = 0;
    +               var topDelta = 0;
    +               if (this.scrollX && this.scrollbars.x) {
    +                       leftDelta = e.targetTouches[0].clientX – this.startX;
    +               }
    +               if (this.scrollY && this.scrollbars.y) {
    +                       topDelta = e.targetTouches[0].clientY – this.startY;
    +               }

    This will only enable iscroll to only care about x/y movements in touchmove if the respective scrollbars were enabled. It should fix your issue…

  63. @Bartman: another way of fixing ajax/refresh problems is to put a call to refresh() at the beginning of the onTouchStart function. Basically, make it look like this:
    onTouchStart: function(e) {

    So you won’t have to care about calling refresh() when your things finally came in from the server. This is quite annoying because the view shouldn’t know when it’s done populating.

  64. Once i use this with like a list of items (clickable) once i slightly touch one its scrolls to the top. Thats kinda irritating, is there a fix?

  65. Has anyone using this script faced flicker issues when you have a lot of rows to be displayed in the div?

  66. As already said, I’m working on a whole framework for iPhone. I’m rewriting the scroller at the moment. You can see a preliminary version online at (on your iphone, android or simulator). I’ll post more details about the framework in the coming days.

  67. Thanks a lot for this solution!

    I was wondering how I could toggle the scroll-ability of an iScroll on and off, I’m still new to jQeury and tried different tactics, but it just doesn’t seem to work.

  68. hi i had implemented this code in one of my project…. but even though scrolling function is there ….. it does not shows the scroll bars while scrolling..can anyboby tell me the reason for this….and can anyone tell me…wat the scrollbars parameter in iscroll method means…

  69. Did anyone use this successfully with jQTouch?

    Once I add a wrapper my whole app goes nuts. Instead of just showing the current page, I see the divs I have on that file…

  70. Hi Matteo, thanks for the great work!

    I have 2 small issues with 3.0alpha5. Maybe you want to consider changing it:

    – Line 276 and 278 seem to be accidentally doubled, I guess you could drop one

    – the ‘click’ event triggering on line 356 should be changed from initEvent to initMouseEvent in order to pass clientX and clientY tap positions. Some people (like me e.g.) want to evaluate these values…

    theEvent.initMouseEvent( ‘click’, true, false, window, 0, this.startX, this.startY, this.startX, this.startY, false, false, false, false, 0, null );




  71. This is working very well for me using code from

    Only blockers I have now are:

    1) scrolling freeze due to a missing touchmove event. I am not sure if I’m scrolling too fast or I am scrolling off the page or what…

    2) flashing while scrolling because of images that are outside of viewing area. Once I scroll down completely (8000px), then all images seem to be cached and then I don’t see the flashing anymore.

    Keep up the good work!

  72. Heyo,

    This looks great. I have a Droid, and would love to help test android compatibility. Currently, the demo you have works for the first gesture, but further drags fail to have any effect. Let me know if I can be of any use to you!

  73. Hi Matteo,

    Great work on GhostTouch! I’m noticing a bug regarding opacity. When I refresh my page sometimes the opacity for the scrolling window is not set back to 1.0. I notice you set the opacity to almost invisible in order to scroll the entire window to the bottom then pop back up again. After it pops back up, it should set the opacity back to 1.0 right? For some reason it doesn’t always do this.


  74. First of all thanks for this awesome script.

    I got a question I’m trying to have a fixed footer I did this via position:fixed and bottom:0px it works great but the viewport is like at a fixed size.

    I tried editing the wrapper height but that didn’t see to work do I have to edit the height in the javascript? or is this something I can do via css?

    Thanks again.

  75. Hi,

    This script seems to be a great solution to the annoying scrolling div problem on the ipod/iphone. However, it seems to turn off normal scrolling. I have a section of my site as a scrolling div. I still want people to be able to zoom in and out and that means being able to use the usual scroll bars.

    As it is, once you scroll in, you can’t move around – is there any way around this? Or is this script restricted to sites that fit completely within the viewport?

  76. Hi Matteo,
    I experienced an issue adding another top fixed element at the base of the navigation bar (I’m using JQtouch).

    The new element causes the page not to be scrolled completely. The footer part is hidden by the browser toolbar. What’s wrong? How may I solve this problem?

    Thanks in advance and Happy Easter.


  77. Thanks Matteo for sharing this script with all of us.
    I have a problem with the refresh(), when using scroll in div elements (as oppose to just using innerHTML).
    It seems to be working ok if the scroll area doesn’t have nested div. I placed a debug statement in the refresh function, and the offsetHeight and the parentNode.clientHeight are set correctly when I don;t have div, and so does the maxScroll.
    However, when I placed images using div element using ajax, the calling refresh, the offsetHeight is set to 1, and the parentNode.clientHeight is set to a high number, therefor setting the maxScroll to 0, causing the scroll area to be non-scrollable.

    Idea anyone?

  78. I found a walk-around that might help others who had problem with refresh() not refreshing…If I placed a simple text value at the end of my scroll area (which had only sections), the refresh() works fine.

  79. ok, i reset the content inside the scroller div via ajax, but it seems the hieght of the scroller div does not change accordingly, any ideas?

  80. I can confirm that this script works on the iPad.

    What I am wondering is if Google does the same thing on The block on the left hand side which fills with search results (hover over a major city then search for “burger”). On the iPad in safari (not the maps app), if that search results block overflows, you van scroll just the content of the block. I tried to figure out how they are doing it, but could not. My guess is they are doing CSS transforms as well. Seems more fluid than your script, which makes me wonder if they are doing it differently.

  81. I’m building a prototype ipad webapp similar to the gmail webapp for ipad and using this script. it works fine on the ipad. the only problem is that I’m using jquery to reload the floating (with external html files), which works as expected, but the height of the div doesnt change accordingly with its new content, there for I can’t scroll to the end. Any ideas?

  82. I would very much like to know how google is doing 2 independently scrollable columns in their gmail interface.

    It even works with can scroll both columns at once.

    If anyone can provide a simple ipad example with 2 scrollable columns and a static header, that would be much appreciated.

  83. Webshotspro:
    I’m working on something like that as we speak, using this script. I looked at the gmail soucecode and I don’t understand it. I noticed that the has the same thing when seem on the ipad, I managed to get the code and it is 95% (if not, 100%) javascript. I don’t know much about js. anyway, I can send you the template I’m making if you’d like. email me (

  84. If I see it right they use the same technique used for iscroll. They just scroll images though (set of tiles actually). That’s why I suppose it is so smooth (I just had a quick look, sorry).

  85. @Matteo thanks for your reply.
    I added “float:left” to all my divs but that didn’t help either. Do you have other suggestion?

  86. When loading new content into the scrolling div via ajax how can i get the page to scroll back to the top when the new content is loaded? I have the loader script in a separate .js file and cannot figure out what to call to do this. I can add this.scrollTo(0,0,’0′) inside the iScroll.js to preform this. Any help would be greatly appreciated. Thanks!

  87. Just providing feedback:
    Neither the demo nor ghosttouch are currently working for my one-year-old Android device: Google Ion (equiv. to HTC Magic) running Android 1.5.

    On the demo at, the div does not scroll. I do see both the vertical and horizontal scrollbars appear after the first touch.

    On ghosttouch, at, I don’t see the list appear, but I do see the header. The header does not stay in place while scrolling, however.

    This guy seems wrote something similar — still not *quite* right, but very close:

  88. Matteo thank you so much for providing the script. I am running into a slight problem and was hoping you or someone else could help me. On the initial page load my scrolling content works perfectly, however I have a bunch of navigation links that jump to anchors throughout my content. For example, <a href=”#SECTION_15″>Section 15</a> and once I click (tap) on that the scroll goes haywire. It won’t let me scroll above or below a certain (arbitrarily random) part of the content and other links jump to the wrong part of the page. Do you have any idea what’s going on?

  89. This is great, thanks.

    One issue though, which is not a problem with the script as such.. is that if there is a textarea in the scrolling div then it seems to want to scroll the whole page before it fires off to iScroll.

    I’ve tried document/window/thetextboxid.addEventListener(e){e.preventDefault();} and that works for all but the textarea.

    Does it have different listener events?

    I’ve set overflow:hidden on the body too but it seems to like to create some slack space as it scrolls.


  90. @Matteo – Thank you for the quick response. I am having a hard time figuring out what would be the best practice for getting the Y position of an element? I’ve tried doing a bunch of different things with no luck.

  91. I’ve been using an earlier version of this script for a few months now, excellent work. Recently, however, I’ve begun to experience a bug that I just don’t understand.

    The scroller div seems to be getting duplicated on top of itself. Then the bottom copy seems to scroll, while the top copy sits still, superimposed over the scrolling copy. There is only one occurrence of the scroller div in the source code, and I can’t figure out how else this could be happening…

    Note that this bug was not affected by upgrading to the latest version of your script.

  92. @devhead11: have a look at the contact list example on this very same site =)

    @Billy Duke: I can’t really duplicate your problem. Maybe is something related to your html/css structure.

  93. This is so cool. Such great stuff. Congratulations…. but…
    I’ve tried to add it to my jqTouch page and I just can’t get it to work. I lose scrolling on everything, (including my scroller div).

    Please can anyone explain how best to use this great script within a jqTouch page?
    I see I’m not the only one who can’t figure it out!

    Pretty please!

  94. Thanks for this resource – is there a way to get the “header” to sit on top of the “wrapper” so that the information scrolls under it? Think semi-transparent header where you can see the content underneath when it scrolls. I was thinking it might have to do with z-index’s and putting the header div after the wrapper div is closed, but I can’t get it to work. Maybe someone else can help?


  95. Do you know of any way to keep the tap-highlight effect when a link is tapped inside an iScroll element? It seems that preventDefault disables it so there’s no feedback when something is tapped. Everything else works great — this is just the last thing I need.

  96. I moved these two lines to touchmove instead of touchstart,


    this seems to let you use comboboxs and drop down boxes and still scroll

  97. Hey man great script, I am using it to build an iPad app so far so good but im having problems with the refresh() function. I keep getting the error “myScroll is undefined” whenever I try to complete an jaxa request. Heres my request code:

    function displayResult(id) {
    var url = ‘displa.php’;
    var pars = ‘id=’ + id;
    new Ajax.Request( url, {method: ‘get’, parameters: pars,
    onComplete: function(response){
    Effect.Fade(‘mainContent’, { afterFinish: function(){
    $(‘mainContent’).innerHTML = response.responseText;

    I have tried a bunch of stuff with no luck and without this bit working I don’t know what to do please help!!

  98. Hello Matteo,

    First of all, I have to say this thing could revolutionize Iphone web apps and compete very much with the native applications. I am very much thinking of using it in one of my current works.

    Before starting, like asked before by someone else but saw no reply, is it possible to add text box in the FOOTER and it moves up when the cursor is in that, like in SMS application of Iphone??

    Your reply would be of great help.


  99. I don’t understand, I try to fix horizontal move, but it can’t want to stay fixe.

    In fact, I’m trying to make a slide like in iphone apps. I have a contener wich have a content (the scroller window.
    The content have 650px width, I’ve got two div in this content, wiches float at left.
    Whe I click to the first the second apear with a slide of the first to the left.

    My init :

    var myScroll;

    function loaded() {
    setTimeout( function() {
    document.ontouchmove = function(e) { e.preventDefault(); return false; }
    myScroll = new iScroll( document.getElementById(‘content’), {vScrollBar: true, hScrollBar: false} );
    }, 100);


    window.addEventListener(‘load’, loaded, true);

    Can you give more information.

    I saw in the different coment :
    myScroll = new iScroll( document.getElementById(‘content’),’y’);
    or myScroll = new iScroll( document.getElementById(‘content’),’x’);

    I try there, but no effect.

    Thanks for this good scroll script !

  100. To make it work on both iPhone and Android 1.5 I changed all translate3d(x,y,z) into translate(x,y)
    and change those 2 lines in iScroll.prototype
    setPosition: function (x, y) {
    this._x = (x!=undefined && x !== null) ? x : this._x;
    this._y = (y!=undefined && y !== null) ? y : this._y;


  101. Awesome script! Any ideas what might be causing the stuttering when scrolling on an ipad? I have also noticed that the scrollbar does not have rounded edges, they are squared off. Is this intended?


  102. The scroller is awsome, im just having one problem. When new content is loaded in the scroller and i go back the scroller goes blank.. any ideas?

  103. Great script, but a couple of problems that are still in the latest version ( 3.1 beta 1)

    -text in fields are smudged/garbled while typing, some times the characters are invisible

    -select boxes do not work. (I have tried the two solutions posted above but both do not work)

  104. @James: I can’t replicate your issue. Does it work properly on the simulator or it’s a problem of the real device only?

    @Thomas: I need more details, can’t understand your issue.

    @John: I noticed that the garbled text is most of the time related to the HTML tag structure. Try to keep a strict xhtml document and it should work. I converted all tables to divs for a client and the text is not garbled any more. Also try to always give a background to the elements (do not use “transparent”).

  105. I have tried to incorporate this with JQTouch, and I lose scrolling on absolutely everything. Have you figured out a solution to this?

  106. The scrollbar issue was a CSS typo on my part.

    Stuttering was a bad reference. What appears to be happening is that slow scrolls work fine. Scrolls where I just move up and down and don’t take my finger off the pad works great as well. When I do a fast scroll however, there is a delay and the screen will scroll to either the top of bottom of the scroll height depending on the direction of scroll.

  107. This is just great, thanks a lot!

    I’d like to use iScroll to be able to use scroll a fixed table header row and column with just 1 finger instead of having to use a two-finger gesture:

    I’m failing to get the fixed “header row” and the fixed “header column” to scroll with the table being scrolled (since the “onscroll” event of the scroller-div is not available anymore when using iScroll).

    Any suggestions on how to accomplish this (having additional divs besides the scroller div which scroll automatically when the main div is scrolled, the first vertically, the other horizontally?).

    Any help is greatly appreciated!

  108. @Matteo

    The new version of iScroll which refreshes itself on ajax addition works as desired and its cool ! But the problem is, when one is doing some Dom node manipulations, it appears to be keeping safari busy doing probably refreshing. This is what it appeared to me. I will update if I come up with something specific. Thanks !

  109. This is excellent work. Any chance of running it through jslint to clean it up? Curious as to why you refer to both this._x/_y in your code while also using the this.x/y getters.

    I ask because jslint does not like the getters (and since it’s unlikely that they’re meant to be an external interface they seem superfluous) and because I’ve augmented your stuff with the ability to use Dojo’s DnD functionality. Thanks.

  110. @Mayank, we could add a timeout to the refresh() function, so it is basically called only once if many consecutive DOM modifications are done. Or we could add a refreshON/OFF function to be called programmatically before intense DOM modifications. That’s why I initially didn’t integrate the auto-refresh functionality.

    I’ll try the “timeout” path and see if it works.

    @cpr, yes a clean up is definitely needed.

  111. I’m making a website that has a horizontal scroll which I have working perfectly with iScroll, how ever, and I’m sorry if this has been stated before, but none of the other native gestures work. For example the pinch and vertical scroll dont work when iScroll is included. I only have iScroll for on section of the site, why would it effect the vertical scroll of the browser? Thanks

  112. Cool. Question: How can I turn off the bouncing effect?
    (Seems like the options already carry a flag for deactivating it but it’s not (yet) implemented?)

  113. @Jared: gestures have to be implemented programmatically (sorry, no way to have both scrolling and native gestures)
    @Jean: that functionality will be added soon (thanks for the heads up).

  114. It appears that new content is loaded as you scroll into new areas, but it’s not unloaded from old areas you’ve already been to. This seems to cause memory problems for very big areas. Is there any way to unload content as you scroll away from it? I am using Version 3.0 alpha 5, by the way.

  115. @Eli: That is a good description of what I am experiencing. I did try to change the translate3d’s to translates as stated in the post #134 to see if that would help, and it slowed scrolling down to a crawl.

    @Matteo: Whenever I scroll, it always pauses before scrolling, and it really doesn’t take much of a gesture to have the screen fly to the top or bottom of the scroll height.

    If you have an iPad to play with, I can setup you up with a link and login so you can see what we are referring to.

  116. @James: is this behavior restricted to ipad? does it work properly on the emulator? If you have a demo ready, please send me the url by email. Thanks.

  117. @Matteo

    I have textbox at the footer. On Iphone, when I click on footer, the header doesn’t remain fix but moves up the screen. Is it the issue I am having or is it a bug?

  118. @Matteo

    I will appreciate if you could provide the change in script that makes it possible for footer to align itself in both portrait and landscape position.

  119. @Terry: I have footers on my pages and don’t have any issue with them aligning when changing back and fourth from landscape to portrait. For proper scaling, make sure NOT to include the meta tag that forces the scale to 1.0: .

  120. @James

    Thanks for the response. I have chat thing working with header having the name of the other person. I want header to be fix at all times. The footer should remain at bottom and fix at all times. Now what happens is that when I click on textbox in footer, Iphone keyboard moves everything up as it does in normal page. Hence, the header does not remain fix.

    Need help in this!

  121. I think you should specifically state that div.scroller and div.wrapper – or the element that scrolls and its parent for that matter – need to have:

    padding: 0;
    margin: 0;

    If not the viewport becomes that amount of pixels off after an orientationchange event. Or it should be fixed somehow in the refresh() method, I’ve been looking into it but could not find a fix asap.

  122. Found that removing width – effectively defaulting it to ‘width: auto;’ – from the elements did the trick (also from #header and #footer). But on my a bit ancient iphone 3g I do experience some flickering when iscroll.js starts. I even added a setTimeout(startScroller, 2000); to be sure it is not the data I’m loading. It is probably related to my slow device since I’ve only seen one other poster mentioning this.

    Thanks a lot anyways.

  123. @James

    As stated before, that solution does not fix the problem. It only disabled iscroll for the page the select element is in, thus enabling the select element but the scrolling ceases.

  124. I tried the solution posted @19 and it works with the scrolling. Sorry for the confusion.

  125. Here is a follow up to the drop down situation. Everything works fine except after the selectbox is selected and the iphone menu is brought which displays the select options – the scrolling region gets messed up. After selecting an option the content is scrolled all the way up and it is hard to reset it back to place. I will try looking at that code at handlevent and see if I can possibly add a myScroll.reset call in there?

  126. @Terry: that is a know bug. A lot of hacks are needed to prevent that behavior, nothing that can be explained here in a comment. If you are in a hurry, you may consider hiring me, otherwise please wait until an official workaround is found and posted. I’m trying to make the script as flawless as possible, as soon as I find bug fixes I post them here.

    To all: Do you think we should open a google group for iscroll support?

  127. Thanks Matteo! Yes I think group/forum will be a great initiative as comments are not a nice place for discussing bugs!

    I will contact you soon and discuss the project.


  128. I’ll give $5 to the person who can fix the issue I am getting. After a select box is opened and the options appear at the bottom (iphone/ipod) the scroll content is pushed upward and then it is impossible to scroll to it. I tried using refresh() but no avail.

  129. I am using this framework for scroll, i have a prob using it in a jsp page where is form tag. when i use a form tag, the touch scroll disappears and normal tag appears on the page.

    Any help please

  130. Thank you so much for this fantastic script!

    I have limited JS knowledge but managed to get it to work. There’s only one problem. My #scroller contains a that is an accordion which opens a child after clicking on the . It does that with a jQuery slideUp() and slideDown() and works smoothly in Safari. On the iPhone the scroll experience is very jerky and jumps all over the place. I assume the jumping accordion is because of the animated change of height which happens in the #scroller and the generally jerky scrolling has something to do with rendering of the elements. There are only about 20 elements with a corresponding but they all use CSS gradients and rgba. Could that be the problem why the performance is so poor? Is there anything I can do?

    1. Hard to say without looking at the code. Generally speaking jquery does not use HW accelerated functions, so that’s why the jerky accordion animations. Also alpha, shadows and gradients impact on performance.

    2. 1) At the end of each slideDown/Up you have to call the iScroll refresh() function.
      2) You can’t use jquery for slidedown/up. I’m afraid you should develop your own hw accelerated accordion. Maybe I’ll work on something like that in the near future.

    3. Thanks Matteo, I really appreciate your input!

      I tried to call the refresh function but it didn’t really change anything.

      I now tried using CSS transition, changing the class names onclick with jQuery. This gives me essentially a very basic accordion. (see It’s still very jerky even though the animation is achieved through CSS -webkit-transition and not jQuery. What am I doing wrong?

  131. I am having an issue when there is a large amount of content in the #scroller div. Even if I set the height of the div to something ridiculous like 50000px, I can only scroll a little more than a page length before it bounces back.

    Thanks for your help in advance.

  132. I’m assuming there is no fix for the select box problem where the content in the scroller gets pushed upward.

    Emailed the author and no response

    1. The only solution to the select box problem is to develop a html/js select box alternative. I’m working on it.

      (Sorry for not replying to all in a timely manner, I receive dozens emails every day)

  133. Out of curiosity, is there a reason why the virtual keyboard (for typing in a input text field) does not screw up iscroll, however the select box options do.

  134. I am trying to find away the select box issue. For now I am trying to use radio boxes instead by using them as options and placing them in a height limited div to show only one at a time, and then have iscroll scroll that div to see the other radio buttons but I cannot figure out how to set up another iscroll within a iscroll ?

Comments are closed.