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
Introduction
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.
Samples
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:
- 2.0.0 New methods in fleXenv for custom programming:
- : This method updates all fleXcroll divs on the page. This is the recommended method to update a fleXcroll div.
- : 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:
- : 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.
- : This method sets scroll position. Returns scroll position values in an array.
- : 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:
- : [[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:
- 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 now accepts page and step scrolls alongside pixel scrolls
- Enhanced in 1.7.6 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 ( ), in addition to the scrollbar-move simulation ( )
- 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 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.
Top
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!
Bottom
Download
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.
Guides
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'>
SOME BIG CONTENT THAT WOULD CAUSE SCROLL BARS
</div>
When you add the class
to your divs, fleXcroll will automatically run on these elements on . 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
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.
JavascriptfleXenv.fleXcrollMain('mycustomscroll');
Other methods
More information can be found in the fleXcroll usage guide.
Styling the bars
For all browsers:
- The most basic style would be with background-colors.
- For the most basic style with images, you need 2 images, one for horizontal bar, one for vertical.
- You can also put background-image to scroll-bars base.
- You can add caps to the scroll bar bases, for this, 1 image that contains all 4 cap images is sufficient. (See the example files)
- You can make a flexible streching image for the whole scroll base, style it as if styling the bar with 1 vertical and 1 horizontal image.
- Make sure you style the bars so that the site is accessible if the user has turned off image loading. The example with red scrollbars is actually a bad one as it uses transparent PNG's and currently we don't have a decent fallback method for transparent images, so its contents would not be accessible if the user turned off the images, but that's not the case for the other two examples, so it's your own decision, if you use transparent pngs instead, accessibility is hampered on some conditions. Take a look at the two other examples than the red one for a more accessible approach.
- Make sure you add position: relative to all your floated elements within the fleXcroll targeted div, it fixes many nasty IE bugs.
- Visit here for fixing more IE styling problems.
For IE6 -only when you want to use alpha PNGs:
- IE6 cannot show the transparency of PNGs, for this to work you need the alpha image loader trick
- The styles to IE6 can be fed to IE6 using conditional comments
- Alpha image loader does not support image positioning so you have have seperate images for each style.
- All browsers can use the seperate images used by IE, but it is best to have the images tucked in together to minimize http calls, so I serve the advanced browsers. the combined images, while I server IE6 seperate images. I am only checking for IE6, IE7 handles PNG's alpha pngs really well. Hooray.
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
- Try to make your scrollbars recognizeable as scrollbars. You can go crazy with it, but make it look like a scrollbar nonetheless.
- Make your scrollbars big enough to be easily clicked and dragged.
- Use custom scrollbars when the look is more important than the content itself.
General considerations
- fleXcroll expects your documents to be well formed. I've seen that most problems when using fleXcroll arose from documents that are not conformant to specs: documents with missing closing tags etc.
- fleXcroll requires only very little javascript knowledge, it is easy to install and get it running. However, it does require you to have at least mediocre CSS knowledge to style the bars, and requires you to code your html properly.
- Try not using javascript solutions where accessibility is most important, while I made sure the scroll-bars are user friendly as possible, they cannot compete with the OS default scroll bars.
- Try to do flexible designs for your pages instead of going for pixel-perfect designs. You'll benefit in the end.
- But if you need exact control over your scroll bars, try to use scripts that degrades well when javascript is turned off, and works almost identical on all browsers. fleXcroll is a good candidate for that job.
- fleXcroll doesn't work well when the custom scroll element size is very small elements (about less than 100px tall or wide may cause problems)
- If you are using floated elements within the scroll area, due to an IE bug that causes floated element not to be scrolled, floated elements have to be styled with Position is Everything. , actually this fixes a lot of other IE problems not related with fleXcroll too, so I advise you use it for every floated element anywhere. To fix this and other IE related CSS bugs, please visit
- Scroll bars may not look correct if you use border and padding in your scroll bar styles. Use images + background-color to style the bars
- This script works on Opera 8/9, Firefox (Mac+PC), Webkit, IE5, IE6, IE7Beta2, it does so without using any browser detection for its functions (except only for one place to fix an Opera8.x CSS display bug). It does *not* work for Safari (macintosh) due to bug concerning overflow: hidden scrollbar visibility which is now fixed in the latest builds, and version 1.8.5 and up supports the latest webkit, good news for Safari users.
- When working with horizontal scrollbars, keep in mind that fleXcroll only looks for the immediate children of our elements' width to see whether a horizontal scrollbar is needed due to performance reasons, so if a child of a child of our fleXcrolled div is horizontally big, but it doesn't enlarge its parent, horizontal scrollbars may not be created even if necessary. Just check out the examples and do your own testing for achieving correct results.
- Floats have to be manually cleared at the end of the div for fleXcroll to calculate the size properly, at least for now.
Standards mode
- In standards mode, the scrollers are drawn identical on all major browsers.
Quirks mode or IE 5.x
- In quirks mode, the element we want custom scrolls cannot have borders, otherwise the scrollbars may be obscured. Use a wrapping div instead that has the borders of the actual element will have no borders. It can, however, have a padding. fleXcroll compansates for the padding automatically
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:
- Type of license you'd like to buy
-
To whose name will the license be registered to (could be either a person's name or a company's name.)
- This is usually whoever is paying for the license, this may not necessarily be the site owner, but it is usually the webdeveloper.
- For which site (base url) you want fleXcroll be registered to (not required for unlimited license)
- To whose e-mail address you want the license text be sent to.
After you receive the license text
- If anything goes wrong and you lose or not receive the license text, you can re-request it and I'll send you again.
- You can then replace the public licence text with your personalized license text.
- If you are still not sure about the process, just drop me an e-mail using the contact page, and I'll contact you with proper explanations.
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!