> iScroll
The overflow:scroll for mobile webkit. Project started because webkit for iPhone does not provide a native way to scroll content inside a fixed size (width/height) div. So basically it was impossible to have a fixed header/footer and a scrolling central area. Until now.
This script has been superseded by iScroll 4. This page is kept for historical reasons.

Project info
Project state: ACTIVE (code is actively updated)
Last code update: 2010.10.08 – v3.7.1
Device compatibility: iPhone/Ipod touch >=2.0, Android >=1.5, iPad >=3.2.
Discussion Group
QR Code opens demo page.
Support development
If this script saved your day or you wish to support iScroll and other scripts development you may consider sending some funds via PayPal.
Overview
iScroll was born because mobile webkit (on iPhone, iPod, Android and Pre) does not provide a native way to scroll content inside a fixed width/height element. This unfortunate situation prevents any web-app to have a position:absolute header and/or footer and a scrolling central area for contents.
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 started… But there’s no rose without thorn. Making the scroll feel native has proven more difficult than expected.
How to use
First of all we need to prevent the default behavior of standard touch events. This is easily done adding preventDefault() to the touchmove event. Then initialize the iScroll object on DOMContentLoaded or on window load. Here an example:
function loaded() {
document.addEventListener('touchmove', function(e){ e.preventDefault(); });
myScroll = new iScroll('scroller');
}
document.addEventListener('DOMContentLoaded', loaded);
iScroll takes two parameters. The first is mandatory and is the ID of the element you want to scroll. The second is optional and can be used to pass additional parameters (see below).
On the HTML/CSS side the scrolling area needs to be wrapped by an element which determines the scroller actual size. The following is a common tags configuration for an iScroll.
<div id="wrapper">
<div id="scroller">
<ul>
<li>...</li>
</ul>
</div>
</div>
The #wrapper also needs some classes:
#wrapper {
position:relative;
z-index:1;
width:/* your desired width, auto and 100% are fine */;
height:/* element height */;
overflow:/* hidden|auto|scroll */;
}
That’s it. Enjoy your scrolling. Have a look at the source code of the online example to get a better idea of how the iScroll works.
Syntax
The iScroll syntax is: iScroll(mixed element_id, object options).
element_id, can be both an object pointing to or a string with the ID name of the element to be scrolled. Example: iScroll(document.getElementsByTagName('div')[1]) or iScroll('scroller')
Accepted options are:
- hScrollbar: set to
falseto never show the horizontal scrollbar. The default valuetruemakes the iScroll smartly decide when the scrollbar is needed. Note that if device does not supporttranslate3dhScrollbar is set tofalseby default. - vScrollbar: set to
falseto never show the vertical bar. The default valuetruemakes the iScroll smartly decide when the scrollbar is needed. Note that if device does not supporttranslate3dvScrollbar is set tofalseby default. - bounce: set to
falseto prevent the scroller to bounce outside of boundaries (Android behavior). Defaulttrue(iPhone behavior). - bounceLock:, if set to
truethe scroller stops bouncing if the content is smaller than the visible area. Default:false(as per native iphone scroll). - checkDOMChanges: set to
falseto prevent auto refresh on DOM changes. If you switch off this feature you have to calliScroll.refresh()function programmatically every time the DOM gets modified. If your code makes many subsequent DOM modifications it is suggested to set checkDOMChanges tofalseand to refresh the iScroll only once (ie: when all changes have been done). Defaulttrue. - fadeScrollbar: define wether the scrollbars should fade in/out. Default
trueon iPhone,falseon Android. Set tofalsefor better performance. - momentum: set to
falseto remove the deceleration effect on swipe. Defaulttrueon devices that support translate3d. - shrinkScrollbar: set to
falseto remove the shrinking scrollbars when content is dragged over the boundaries. Defaulttrueon iPhone,falseon Android. It has no impact on performances. - desktopCompatibility: for debug purpose you can set this to
trueto have the script behave on desktop webkit (Safari and Chrome) as it were a touch enabled device. - snap: set to
trueto activate snap scroll. - scrollbarColor: changes the color of the scrollbar. It accepts any valid CSS color (default:
'rgba(0,0,0,0.5)'
Note: options must be sent as object not string. Eg:
myScroll = new iScroll(’scroller’, { checkDOMChanges: false, bounce: false, momentum: false });
Snap scroll
When calling iScroll with “snap” option the scrolling area is subdivided into pages and whenever you swipe the scroll position will always snap to the page. Have a look at the screencast to get an idea.
Probably the best way to use “snap” is by calling it without momentum and scrollbars:
new iScroll('scroller', { snap:true, momentum:false, hScrollbar:false, vScrollbar:false });
If you keep momentum, you get a free-scrolling that will always stop to prefixed positions.
To have a perfect snapping experience the scrolling area should be perfectly divisible by the container size. Eg: If the container width is 200px and you have 10 elements, the whole scroller should be 2000px wide. This is not mandatory as iScroll doesn’t break if the last page is smaller than the container.
Methods
- refresh(): updates all iScroll variables. Useful when the content of the page doesn’t scroll and just “jumps back”. Call refresh() inside a zero
setTimeout. Eg:setTimeout(function () { myScroll.refresh() }, 0). - scrollTo(x, y, timeout): scrolls to any x,y location inside the scrolling area.
- scrollToElement(el, runtime): scrolls to any element inside the scrolling area.
elmust be a CSS3 selector. Eg:scrollToElement("#elementID", '400ms'). - scrollToPage(pageX, pageY, runtime): if snap option is active, scrolls to any page.
pageXandpageYcan be an integer orprev/next. Two keywords that snap to previous or next page in the raw. The “carousel” example in the zip file is a good starting point on using the snap feature. - destroy(full): completely unloads the iScroll. If called with
fullset totrue, the scroller is also removed from the DOM.
Best practices
DOM Changes – If scrolling doesn’t work after an ajax call and DOM change, try to initialize iScroll with checkDOMChanges: false and call refresh() function once the DOM modifications have been done. If this still doesn’t work try to put refresh() inside a 0ms setTimeout. Eg:
setTimeout(function () { myScroll.refresh(); }, 0);
Performance – CSS animations are heavy on the small device CPU. When too many elements are loaded into the scrolling area expect choppy animation. Try to reduce the number of tags inside the scrolling area to the minimum. Try to use just ULs for lists and Ps for paragraphs. Remember that you don’t actually need an anchor to create a button or send an action, so <li><a href="#" onclick="..." />text</a></li> is a waste of tags. You could remove the anchor and place the click event directly on the LI tag.
Try to avoid box-shadow and CSS gradients (especially on Android). I know they are cool and classy, but they don’t play well with CSS animations. Webkit on iPhone seems to handle shadows and gradients a bit better than its counterpart on Android, so you may selectively add/remove features based on the device.
Use a flat color for the #wrapper background, images in the scroller wrapper once again reduce performance.
Important: to preserve resources on devices that don’t support translate3d (namely: Android<2.0) iScroll disables momentum, scrollbars and bounce. You can however reactivate them using the respective options.
Bugs and limitations
Form fields do not play well with CSS animations. Countermeasures have to be adopted on a case-by-case basis.
Please use the issue tracker on Google Code to submit a bug report. You can also follow day by day updates on Google Code.
Future developments
- I’m considering Palm Pre compatibility.
- Check for multiple consecutive changes to the DOM to prevent unnecessary calls to the
refresh()function. - Maybe we can achive better performances with lazy loading and pre-fetching. Lazy loading takes care of loading and unloading elements when they are not needed (ie: out of the screen). Pre-fetching can be used to preload all elements to reduce flickering.
FAQ
Q: Why on Android 1.5/1.6 I’m not seeing the scrollbars?
A: On older devices iScroll disables the scrollbars and other effects. You can reactivate them passing the hScrollbar:true and/or vScrollbar:true options.
Q: Why aren’t you adding feature X?
A: I’d like to keep the iScroll as bare-bone as possible, before adding a new feature I carefully estimate the pros and the cons.
Q: I’ve developed feature X, may I send it to you?
A: Please do! It’s not guaranteed that I will add your feature to the script, but I review all code you send to me.
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?
Revisions history
v3.7.1, 2010.10.08 – Bug fix
v3.7, 2010.10.05 – Lock scrolling direction, added bounceLock and scrollbarColor options, size optimization.
v3.6, 2010.08.24 – Bug Squashing Edition.
v3.6 beta 1, 2010.08.10 – Added snap scroll.
v3.5.1, 2010.07.30 – Mandatory bug fix.
v3.5, 2010.07.27 – Added scrollToElement() method, fixed a bug with scrollbars and multiple iScroll instances, a bit of code clean up.
v3.4.5, 2010.07.04 – Prevent JS error on browsers not supporting WebKitCSSMatrix.
v3.4.4, 2010.06.30 – Better orientation detection.
v3.4.3, 2010.06.27 – Bug fix.
v3.4.2, 2010.06.24 – Bug fix.
v3.4.1, 2010.06.24 – Enhanced shrinking scrollbars.
v3.4, 2010.06.20 – Shrinking scrollbars and preliminary desktop compatibility.
v3.3, 2010.06.11 – Code freeze, let’s go for 3.4.
v3.3 beta 3, 2010.06.10 – Full (?!) Android compatibility.
v3.3 beta 2, 2010.06.08 – Better Android compatibility.
v3.3 beta 1, 2010.06.04 – Added Android >=1.5 compatibility.
v3.2.1, 2010.06.03 – Bug fix.
v3.2, 2010.05.31 – Code clean up.
v3.1 beta 1, 2010.05.06 – Added auto refresh on DOM changes.
v3.0 alpha 1, 2009.11.30 – Complete code rewrite. Scrollbars added. Optimized deceleration.
v2.3, 2009.07.09 – translate() replaced by translate3d().
v2.2, 2009.06.18 – Added OS3.0 compatibility.
v2.1, 2009.02.12 – Added refresh() function.
v2.0, 2009.02.03 – Optimized deceleration formula.
v1.1, 2009.01.18 – Removed timers.
v1.0, 2009.01.03 – Initial release.
I want to add an up and down arrow to my iScroll that scrolls vertically but am having a hard time getting it to work. The div’s ScrollTop always returns 0 and I am unable to program the up or down arrow to scroll 60 pixels per click either direction. Is there a function I can call with iScroll to achieve this?
check myScroll.x and y
Certainly you *could* roll your own framework, but that idea died with prototype. I’ve used so many jquery plugins I lost count: templates, validation, bbq, modal, visualize, slider, etc. If you’re worried about space, its called HTML5 app cache. Download once and done. And I don’t have to worry about IE, or God knows who else thinks its a good idea to come out with another mobile platform.
Any ideas how to get this to work on blackberry? Seems to be working a treat on iphone and android.
I too have the same issue. Does it work for BB? I am trying to create an app for BB using PhoneGap.
Can you try the dev release on github?
https://github.com/cubiq/iscroll
Matteo,
I tried but no luck…
cool man !
use it in my app, rocks !
hey,
i have a problem with i scroll and jqtouch. both works great with safari but not with the iphone sdk simulator.
when i click on the link in the “iscroll” list (Link), it doesn’t slide to the next page. when i delete “” the slide works with the simulator but not the scroll.
maybe iscroll and jqtouch are not compatible or i made a big mistake? i don’t know.
any ideas?
thx
On a related CSS issue, unless I explicitly set the height of scroller to be larger than wrapper, scroller seems to be limited to height of wrapper, hence no scrolling.
I want to leave the height of scroller auto, because its contents vary in the long term.
I’ve tried with my own div contents, and with your ul content, same thing – scroller is cropped.
Any ideas? Android 2.2.1.
Solved. Image elements within scroller were rendering and flowing at full height, but wrapper height was not growing with them. When I explicitly set the height of the list elements. Problem solved.
How did you do it? I have a similar problem. I am populating a div dynamically. However My scroller div is not scrolling
Fantastic product!
Way better than scrollTouch that is available on jquery site
Maybe think about releasing it there?
Hi Matteo,
really great work – works like a charm.
but sadly – nothing else works in my test.
I can’t click on anything else but the scroller (images).
the section is same as in your horizontal example.
I did post this morning in the group, but it never showed up
really no link works. I’m getting frustrated, because I try since yesterday. with and without jquerytouch. now totally clean in this example:
maybe you could take a little look:
titel
titel
titel
titel
titel
titel
titel
some link
maybe I’m totally blind or too stupid?
thank you very much
best, tom
Great work!
We are trying to implement this on a helpdesk system for out IT department. It’s working very well, but then I add a SIGPAD on one of my pages.
This is for signing documents. You write with your finger, but then the iScroll keeps moving it araound…
Is there a way to disable it when sigpad has focus?
i had same demand and found a solution for that.
just set scroll.enable = false
of course you have to set it true when blur
scroll.enabled = true;
scroll is
var scroll;
scroll = new iScroll(“id”);
i hope it can be helpful.
What a wonderful script, my html 5 app is really starting to come alive on the iPad. Many thanks!
nice work!
the hover effect does not work on android.
e.g
ul{width:100%;list-style:none;}
li:hover{background:blue;}
1
2
3
Love this, but one question, is it possible to have a landscape scroll inside your slide in menu?
Done it now, but I can’t touch links or anything, I can only scroll inside the slide in menu and close the slide in menu
Hello all,
Does iScroll support BlackBerry? if support which version it can?
Hi, I was wondering if anyone has implemented a circular/infinite version of this iScroll?
to enable html select you must comment out the e.preventDefault in the iscroll.js file. The veritcal iscroll still works for me!
for got to mention to apply the prevent outside of the iscroll.js like this:
$(‘#scroller’).bind(‘touchmove’,function(e){
e.preventDefault();
});
is it possible to have 2 vscroller? i like to snap magazine pages and simple scrolling dopple pages …
To solve the selectbox scroll top issue use:
$(‘select’).bind(‘blur’,function(){scrollTo(0,0)});
Worked for me.
Thanks Matteo for providing your code.
I think it works only on iPhone.
Thank you for the excellent and lightweight script.
Have anyone ever successfully use iScroll with a pop-up or modal dialog? I am really cracking my head…
maybe you need lightbox not iscroll. you can find lightbox for mobile with swipe function.
i tried it on my mobile site and works good on iphone/ipod touch 4
i have iscroll.js on my asp.net for gridview control alone and i have dropdown list on gridview .
1.once if i add the isDOMContentLoaded method then dropdown is not selecting in ipad
2.if am not adding isDOMContentLoaded then dropdown selection works in ipad
can u please help me …..
Venkatesh
vsomasundarm2@ballytech.com
Brilliant script, thank you SOOO much!!
Just one thing: On black / dark backgrounds, the (native) iPhone scrollbars have a thin bright border to separate them from the background. Can this be added to your work too?
I managed to hack your script badly enough to achieve this, but only partially.
scrollbars border has been added to iscroll4 (soon to be released)
awesome script! I’m using it to hack a prototype together.
Does anyone know why the quality of ‘-webkit-transform:scale()’ is effected by this script?
With the script active the outcome of a scale(8) the edges of object become very blurry on text and boxes. With the script disabled, suddenly everything turns sharp again…
Anyone know what’s going there?
This hack saved me an incredible amount of time, I’ll never be able to thank you enough for that
I’ll share with you a way to make the footer div actually transparent, because that’s what I had to achieve in effect.
1. Open the example: http://cubiq.org/dropbox/iscroll/index.html?v=3.7.1 It will be needed for use as an example.
2. Go to the css clause for the footer div and add “margin-top” to that clause that has the same value as the height value for the footer div, only make it negative. My footer is 39px high, so I give it a margin-top of “-39px”.
3. Now move to the head section of your page, where the iScroll js code is. Look up the line:
wrapperH = window.innerHeight – headerH – footerH;
In my case, I don’t want a static header, so I’ve commented mine out, and modify wrapperH to be equal to the window’s height minus the footer’s height but substracting the footer’s height from that value. This will give the div zero height but the negative margin-top will still make its contents show above the hidden footer div. So, for my hidden header page with the 39px high footer, the line will become:
wrapperH = window.innerHeight – /* headerH -*/ (footerH-39);
Now put a transparent png for the footer’s background or just give css opacity to the footer div. The wrapper’s contents should show under the now-translucent footer. How’s that?!
Is anyone getting really poor, essentially unusable performance on Android? I’m looking at this page on my Droid 2 running Android 2.2:
http://cubiq.org/dropbox/iscroll/index.html?v=3.7.1
Scrolling is practically impossible… The list doesn’t want to respond to scrolling.
Hi,
great plug-in. i am facing this problem with iphone:
while trying to make the scrollable area longer with jQuery:
jQuery(“#wrapper”).height(jQuery(“#wrapper”).height() + 15);
setTimeout(function () { myScroll.refresh() }, 0);
my scrollable area actually expands as i wish. but when i begin to scroll the old height suddenly gets set to the ‘original’ value. this doesn’t happen in android.
am i missing something? would be great if you could help.
thanks a lot.
best regards Koray.
Hello, gr8 work, I want use this code on a big website can i use this code for that propuse?
yes, of course. Why not? It’s MIT licensed
when I have a combobox in the scroll does not work, what is the reason why this happens? and how I can fix it?
if you wanted to zoom in the content of the page, but not in footer or header. What should I do?
Please help me with these issues
can i have 2 scroll objects in 1 page?
yes, of course.
When i look at the demo on my iphone it disables my ability to zoom in and out. Is this necessary or can I allow zooming and still use a fixed position?
Hi
Love iScroll.
However, how do I implement horizontal AND vertical scrolling within a fixed frame, or is this not possible ?
Thanks
Steve
Hello, see the examples
Hi
I checked out the examples and none of them implement two directional scrolling unless I’m missing one. Which example will show me the code that I need?
Thanks
Just set the width of the scroller higher than the wrapper width. I see no issue here. Have a look at the horizontal example.
I never believed it was an issue, I just needed pointing in the right direction which you have done. It is now working as required. THANKS.
Hi,
for the first – sorry for my English it is not so well :/.
I tried to use your great scrolling stuff and I would like to use it in general in my project. I found out the problem when some form elements are focused in scrolling area.
I created small test page – http://kristal.php5.cz/scroll.html.
I focus some elements when page is loaded. Did you have to deal with this issue? I am not very good in webkit – I am pretty sure that it should be possible to deal with it some how. I have some ideas but my knowledges of webkit are realy very small.
Again sorry for my english.
I could reset scroll area by this way:
iScroll.wrapper.scrollTop = “0px”
iScroll.wrapper.scrollLeft = “0px”
but I would prefer some “better” way. I tried to call iScroll.setPosition(0,0) but it does not work to me.
use scrollTo(x,y,time)
I have tried it but it did not help.
Only scrollTop = “0px” helped :-O.
This may be a very nice project, but I don’t see the use of it: in iOS you need to drag with 3 fingers and the content in your fixed div will scroll. Am I missing something?
this has been addressed many times. this is a solution for 1 finger scroll, that is crucial for webapps (less on web sites).
in examples/carousel,
I can’t vertical scrolling on ‘wrapper’ DIV.
how can do that?
ps. i’m so sorry, my english is not good.