FleXcroll, Flexible and Accessible Custom Scroll Bars

A Cross Browser* and Standards Compliant Custom ScrollBar Script by Hesido

featuring touch scroll for iPhone Safari

updated on 05.06.2016; Switched to FastSpring for payment.

updated on 03.02.2013; version 2.1.1, fleXcroll overhaul for click, touchmove and keyboard event handling with many bugfixes and new styling elements for easier customization of scrollbars.

updated on 23.05.2010; version 2.0.0, fleXcroll major update for consistency and lots of backbone changes, including iPhone Safari support.

older updates are discarded

created on 09.08.2005


You sometimes need custom scrollbars to go with your design intensive web-page, and I have come up with a cross-browser javascript solution that let's you use (X)HTML without having to resort to Flash. Custom scrollbars do not have to be inaccessible: fleXcroll supports mouse-wheel and keyboard scroll (from version 1.5.0), and text selection aid (from version 1.7.5) so people can text-select overflowed contents, and it also supports iPhone touch scrolling inside overflow: auto divs, making it behave almost the same as (and in some cases better than(!)) OS default scroll bars. Even with all its features, fleXcroll will not be able to satisfy some users, so that's why I made it fully unobtrusive, making it a solution that allows content to be accessible when javascript is turned off, and it does a pretty good job of behaviour abstraction from html: you write your html like the way you are used to, except there are a few things you need to be careful about, and fleXcroll handles the rest. This gives you an advantage, you don't write specific html that would only look right when fleXcroll is active; your content should look right even when you revert to a non-fleXcroll version of your site. Thanks to asyncore for giving my script its name. Also, a big thanks goes out to sherool@my.Opera for suggestions. Additional thanks to filbo, userDude, burnout426@my.Opera for their support. Last but not least: there's little I can do to show my gratitude to Yusuf Cem Kaplan@Blesseville, who came up with fleXcroll's slick logo, and greetings to all who have bought licenses either to show support or use fleXcroll in a commercial product.


Please take a look at the source of this html page for some examples on how to use fleXcroll in a dynamic setting. fleXcroll can cope with dynamic updates such as dynamic content injected via AJAX, and can be controlled from outside, and fleXcroll now provides transparent support for anchor id's:
Clear Test Div : Add P : Remove P : Switch wide/narrow
Move Scrollbars relatively : Scroll content to 50px left, 50px down

Features & Brief history of fleXcroll:
  • Enhanced in 2.1.1 Better dynamic forms support.
  • Enhanced in 2.1.1 Better dynamic in-page anchor support.
  • 2.1.1 Keyboard handling bug is squashed.
  • Enhanced in 2.1.1 Performance fixes.
  • 2.1.1 Removed jumpiness when calculating content on slower computer.
  • 2.1.1 True arrow support. Padded portions are considered arrow keys to keep the backwards compatilibity.
  • Enhanced 2.1.1 Better iOs touch click handling
  • 2.1.1 New styling elements, .vscrollerbarmid, .hscrollerbarmid, .vscrollerbasemid, .hscrollerbasemid : these are elements that can be used to style the middle part of the scrollbar and scrollbase (scrolltrack).
  • 2.1.1 Mousewheel not operating bug when user used mousewheel to scroll to the edge, then moved the scrollbar using the mouse, and went back to mousewheel scrolling towards the edge.
  • 2.1.1 Keyboard support for Opera Next.
  • 2.1.1 Fix click handler assuming classname as text bug.
  • 2.0.0 Safari on iPhone OS support, fleXcroll is now iPhone, iPad, iPod Touch compatible.
  • 2.0.0 All functions are wrapped under a window global: window.fleXenv
  • 2.0.0 New methods in fleXenv for custom programming:
    • fleXenv.updateScrollBars(): This method updates all fleXcroll divs on the page. This is the recommended method to update a fleXcroll div.
    • fleXenv.scrollTo(): This method scrolls to an element inside a fleXcroll div.
  • 2.0.0 All fleXcroll related functions that are added to the div object is moved under fleXcroll object, the other methods are deprecated, should no longer be used:
    • div.fleXcroll.updateScrollBars(): This method tells the fleXcroll div to update its scrollbars. Should be used right after a change in content, usually after your AJAX script does innerHTML.
    • div.fleXcroll.setScrollPos(): This method sets scroll position. Returns scroll position values in an array.
    • div.fleXcroll.scrollContent(): This method does a relative scroll. Returns scroll position values in an array.
  • 2.0.0 All fleXcroll related data are set under div.fleXdata, the most useful is:
    • div.fleXdata.scrollPosition: [[currentXscrollPos,maxXscrollPos],[currentYscrollPos,maxYscrollPos]]
  • 2.0.0 Support for external scrollbars. This allows you to write the html code for your scrollbar.
  • Enhanced in 2.0.0 Now, scrollbar positions are calculated from content position, previously content position was calculated from scrollbar positions. This is good for ajax changes that does not clear the content but adds to the content and a number of other things.
  • 1.9.5f Workaround for nasty IE8 bug that cannot calculate sizes of invisible elements properly. fleXcroll now works in IE8 standards mode.
  • 1.9.5 Fixes a style bug caused by the drag&drop workaround, removed this workaround until I figure out a way that does not break styles.
  • 1.9.4 Fixed bug with center: align or center: right would cause a mis-sized content space
  • 1.9.4 fleXcroll now compensates for the mega silly Safari 3 bug that incorrectly reports undeclared z-index'es as 'normal'. The word they were looking for was 'auto'. ( There is nothing such as 'normal' as initial value in W3 standards, I'm much sorry to let you know.
  • 1.9.4 Added better support for visibility checks, making fleXcroll compatible with some accordion scripts
  • 1.9.3 fleXcroll adds support for named anchor targets. Earlier, only id targets were supported.
  • 1.9.2 fleXcroll can now be applied using just a class-name.
  • 1.9.2 fleXcroll now adds a new pseudo event to window element: window.onfleXcrollRun
    • window.onfleXcrollRun can be set as a function, and this function will get run after fleXcroll initializes
  • 1.9.2 fleXcroll can be used as a news-ticker, this is just an example of what else can be done using fleXcroll.
  • 1.9.2 Fixed bug where scrollbars remained visible wheb the div is set to visibility: invisible
  • 1.8.9 Brings transparent support for anchor id's, and url's with id's.
  • 1.8.5 Now comes in its compressed form as well as uncompressed, and it is down to about 13KB's, from about 20KB's.
  • 1.8.5 Commercial license owners now has access to developer commented version, for their internal script development.
  • 1.8.5 Supports Webkit, the engine used in Safari, meaning future Safari's and current users of latest webkits will also enjoy flexcroll!
  • 1.8.5 CSS setting to always display scrollbase even when not necessary is now possible, see examples.
  • 1.8.5 CSS setting to hide scrollbars is now supported, this will allow users to script their own scrollers.
  • Embedded accessibility addons:
    • 1.7.5 Text selection aid, so users can scroll-select overflowed content
    • 1.5.0 Mousewheel Support (IE, Firefox, Opera9)
    • 1.5.0 Keyboard focusability and keyboard scrolling (IE, Firefox) (Operas prior to O9 cannot fully make use of this feature)
  • 1.7.7 Firefox font-resize detect
  • Enhanced in 1.7.7 Faster scrollbar response
  • Enhanced in 1.7.7 Container resize support
  • Enhanced in 1.7.6 Mousewheel and scroll-base click reaction
  • Enhanced in 1.7.5 Keyboard reaction
  • Enhanced in 1.7.5 element.contentScroll() now accepts page and step scrolls alongside pixel scrolls
  • Enhanced in 1.7.6 element.commitScroll() now behaves the same as contentScroll, no more scrollbar move simulation, because it is no longer needed
  • 1.7.1 Support for variable percentage widths, demonstration will be available soon.
  • 1.7.1 Support for manual change in container size
  • 1.7.1 Better cross-browser padding support in quirksmode
  • 1.7.1 More stable decision on which scrollbar to display
  • 1.6.0 Re-coded entirely with DOM methods, no more destructive innerHTML, gets along much better with other standards obedient scripts regardless of execution order
  • 1.6.0 Method to do content scroll in pixels (element.contentScroll), in addition to the scrollbar-move simulation (element.commitScroll)
  • 1.6.0 Single global function
  • 1.5.0 Enhanced accessibility behaviours (mousewheel can scroll horizontally when horizontal bar is hovered or the element is only a horizontal scrollable element, making it a better option than OS default scrollbars when user has a single mousewheel.
  • 1.5.0 Control scrollbars from outside using the commitScroll method (Depreciated entirely as of 1.7.6 element.contentScroll is more meaningful and can handle page/step scrolls.)
  • 1.1.0 Can cope with dynamic changes to scroll size (on window resize, on text resize, on window load)
  • 1.1.0 Updates itself everytime a scrollbar is clicked, so your content is accessible if any size change is missed, great for firefox users who like to change their font sizes after the page is loaded!
  • 1.1.0 You can manually tell flexcrolled div to update its size, allowing you to inject dynamic content into fleXcrolled content
  • Fully customizable look using CSS only, no script editing to change the look.
  • No limit on how many scrollers there can be on a page
  • Each scroller on page can have its own style
  • Auto decide whether horizontal or vertical scrollbars are needed.
  • Support for adding custom scrollbars to absolute positioned and floated elements
  • Proper support for padding and borders without the need of an extra wrapper div inside the custom-scroll-bar element
  • Mimics default browser behaviour when deciding which scroll bars are to be used*
  • No extra markup needed**. Please check the html source.
  • No inline javascript needed (Can be run externally)
  • If the user has turned off javascript or the user agent has no javascript capability, there is no accessibility problems as the page falls back to OS default scrollers, please check with javascript turned off.
  • Uses DOM compliant methods.
  • Cross-browser, works with Opera, Firefox, IE down to IE5.0, Webkit***, Safari on iPhone Os
  • Free for non-commercial use.
  • No extra libraries needed, all code in one compact code.
  • Some more I forgot.

*There are a few situations where fleXcroll behaves differently.
**Floats have to be manually cleared at the end of the div for fleXcroll to calculate the size properly, at least for now.
***Does not work with Safari 2.0 and earlier (tho without creating any accessibility problems) due to a Safari bug, which is now fixed in the latest builds of Webkit. User of webkit will be able to enjoy fleXcroll scrollbars.


Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque ultrices facilisis risus. Aenean sollicitudin imperdiet justo. Nam sed nulla sed metus blandit pretium. Morbi odio. Maecenas vestibulum dolor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam in elit. Nam venenatis urna id diam. Quisque porta. Sed ultricies, sem vel gravida mollis, pede lectus vehicula orci, quis sodales mauris velit vitae dui. Sed tincidunt mauris ut libero. Suspendisse potenti. Praesent adipiscing. Sed sem. Ut non justo. Cras pretium nibh scelerisque nibh hendrerit venenatis.

Nullam lobortis, dui nec accumsan molestie, ligula libero porta urna, in tincidunt ante lacus ac diam. Vestibulum erat risus, scelerisque non, mattis sit amet, aliquet convallis, enim. Sed mattis. Phasellus tristique. Nullam metus ipsum, sagittis at, tempor non, consectetuer eget, massa. Curabitur metus lacus, fringilla ac, interdum condimentum, hendrerit non, est. Morbi iaculis. Aenean lacus lectus, lacinia eget, hendrerit id, imperdiet ac, nisl. Praesent metus. Morbi mi elit, lacinia fringilla, luctus ut, tempor at, diam. Nulla arcu nibh, condimentum fringilla, nonummy et, volutpat eget, orci. Suspendisse et dui. Integer eget lorem. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Suspendisse vitae odio. Sed risus nisl, mattis vitae, imperdiet et, semper nec, tellus. Quisque adipiscing, neque id faucibus fringilla, eros augue ultricies orci, quis tincidunt tortor elit gravida ligula. Suspendisse suscipit sem sit amet ipsum. Etiam elit.

Aenean ullamcorper leo a neque. Ut eros risus, ornare sed, luctus sit amet, mollis ut, nisl. Proin dui. Aliquam suscipit. Vestibulum nisl wisi, eleifend at, placerat et, lobortis vitae, dui. Nulla dapibus pretium nulla. In hac habitasse platea dictumst. Cras ultricies nisl eu est. Aliquam ultrices, orci in dapibus facilisis, tortor pede bibendum neque, eget vestibulum lectus wisi vitae orci. Phasellus quis metus. In turpis diam, varius in, pulvinar sit amet, commodo ut, wisi. Donec leo nibh, iaculis in, facilisis non, mollis eget, eros. Morbi sem.

Nunc sed arcu. Phasellus euismod tincidunt eros. Proin ac purus. In dictum ante vitae libero. Proin pede. Pellentesque tellus ipsum, semper quis, dapibus eget, ultricies ac, pede. Aenean tristique tincidunt lorem. Aenean eget eros quis tellus tincidunt condimentum. Aliquam tempor, erat sit amet condimentum sagittis, ante sapien dapibus lectus, in tempor mauris sem non metus. Nam id orci. Nulla dignissim, felis in euismod tempor, neque turpis suscipit urna, id tristique mauris eros et dui.

Aliquam eget felis id elit congue tempus. Maecenas a velit. Sed egestas malesuada sapien. In sapien. Integer sit amet massa vitae justo vulputate viverra. Fusce suscipit, mi a lacinia lobortis, urna enim consectetuer risus, et ultrices ante nulla nec mauris. Integer pulvinar aliquet turpis. Phasellus fermentum diam at mauris. Ut nulla est, rhoncus sed, malesuada eget, rutrum ac, nunc. Curabitur in ante.

I can be scrolled-to using an anchor id link!


Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque ultrices facilisis risus. Aenean sollicitudin imperdiet justo.


Download the script here: If you get an error message while trying to download the file, please diable any web-anonymizer software that blocks referral headers, some internet security software may also disable the referral header.

Stay Up-To-Date

I constantly work on fleXcroll to make it better. You can follow fleXcroll on twitter (recommended), or subscribe to my feed.


Some more points

Working to get it just right

It took quite a while for this script to mature. After some hard scripting work and lots of experiments, I managed to come up with a script that worked on Opera, Firefox, IE, now IE7Beta2 (even down to IE5.0 if you do not put borders around the actual custom scrolled element), that needs no extra markup whatsoever. You can apply it to any div with fixed width and height with no special pre-setting. Anyway, while I have yet to see a better accessible custom scrollbar (my personal view), it was not possible to make this as accessible as operating system default scroll-bars. But here is the catch: As the script needs no pre-setting and no extra markup, the scrollable elements will still be scrollable even when javascript is turned off, this time with OS default scrollers. You can also give your visitors a setting to turn your custom scrollbars off, store it in a cookie, so if they really hate this, they still can happily access your site.

Fees: Free for non commercial uses

You can use the script to enhance your personal site or implement it in non-profit community sites without paying a dime. A link to hesido.com is much appreciated, but not required. These type of websites include: Charity websites, personal sites, blogs, etc.

Important: Taxes may apply based on your location.

For commercial uses which include but is not limited to any paid work whether you are charging extra for the script or not, you have to pay $30 (U.S.D.) for a single website, $25 extra for a second website, and another 15$ extra for unlimited number of websites ($70 U.S in total for the unlimited web-site license). Commercial website means any website involving in commercial activities (a company website, web-design portfolio site, an online shop etc.) You can show your support to hesido.com by buying a license, even if you do not plan on using it commercially. Single website licenses can later be upgraded to unlimited use license, with the fee paid for the single website is counted towards your unlimited use license, e.g. if you already own a single website license, you can ugrade to the unlimited use license for $40 U.S.

It covers your back when it can't work!

Degrading is the most important feature of the script, it degrades excellently without breaking anything if the user has turned off javascript, or when the User Agent has no javascript support. Why not try this page with Javascript turned off? You'll see the content in the srollable elements are still accessible.

Example Usage

The easiest way to play with and learn about fleXcroll is using Opera: Just save this page with "html with images" in a folder, and all the required files, the images, the javascript files will be saved there locally for you to temper with. (However this will obviously not save IE png hack images, you can optionally extract them from the archive)

Let's say we have an element with the id 'mycustomscroll'. Here is the necessary CSS (exluding the scroll bar styles):

Styling the target div element

CSS Style
#mycustomscroll {
	width: 290px;
	height: 330px;
	overflow: auto;
	position: relative;

Position:relative is only needed because IE has a bug with overflow:auto elements as general. The script also supports elements that are floated or absolutely positioned, and elements with percentage widths. Make sure you have the scroll bar styles and script in the head of the document, either linked or embedded in the html file

Starting fleXcroll: method 1 (preferred method)

Standard HTML
<div id='mycustomscroll' class='flexcroll'>

When you add the class 'flexroll' to your divs, fleXcroll will automatically run on these elements on window.onload. You do not have to add any extra piece of javascript (as of v1.9.2).

If you do not want to wait for total page load, which can take very long on graphics-intensive pages, you can add a 'signalling element' with the id: 'flexcroll-init' at the end of the document. The 'signalling' element can be an empty element, or it can be any element at the end of the body of your html. You can view the html of this page and take a look at the end of the file to see an example and brief explanation.

Starting fleXcroll manually: method 2

This is a deprecated method and is no longer necessary. But if you think adding an extra element for fast execution is unnecessary, or your javascript framework has a better alternive to window.onload, you can use the following piece of script to start fleXcroll on your desired element. You can use Dean Edwards' rather clever domcontentloaded method.


Other methods

More information can be found in the fleXcroll usage guide.

Styling the bars

For all browsers:

For IE6 -only when you want to use alpha PNGs:

Important Notes

Browsers tested to work with fleXcroll

Safari for iPhone OS, Opera 8.5+, Firefox 1.5+ for PC and MAC and Linux, Webkit (MAC), IE5+ has been tested to work with fleXcroll. IE for Mac does not support fleXcroll, it is a discontinued product that has many scripting bugs, and it is blocked from using fleXcroll so IE users on Mac can also browse your content.

Rest of the Mozilla based browsers seem to behave nicely in fleXcroll. Older browsers that does not support the W3 document object model are left with non-fleXcroll version of your site, but they should be able to access the content without problems.

Safari 2.0.4 on Mac has a bug that is now fixed in the latest webkit builds. Safari users browse your site without fleXcroll, but they can access your content without problems due to the unobtrusive nature of fleXcroll. Latest webkit, from version 1.8.5, properly supports fleXcroll, meaning future Safari versions will also support fleXcroll. Safari users can download the latest Webkit to enjoy fleXcroll and the web in general, as Webkit fixes many annoying Safari bugs. Here's a picture of some of the Mac browsers that has proper support for fleXcroll.

Mac testing done using Browsrcamp's VNC server.

For an accessible and useable site

General considerations

Standards mode

Quirks mode or IE 5.x

How To Order a fleXcroll License

You can receive information after sending me an email using the contact page, but if you want to make things fast, you can do the following:

Payment using FastSpring

This is the currently the only payment option:

I need the following information to produce a valid license for you, you'll receive a temporary key from FastSpring, and I'll prepare you a permanent license text using the following information:

After you receive the license text

When you buy a license of fleXcroll, you'll receive all future versions of fleXcroll for no charge for the same type of license, so you will have access to all future versions of fleXcroll for no extra charge, and you will not be affected by price changes. If you like fleXcroll and you are using it for your non-commercial website, you can still show your support by buying a license.

Final Words

I hope you like this piece of code!