The scrollbars on browser windows are not styled by the website itself, or even generally by the browser. They come from the operating system itself.
The desire to customize the style of these scrollbars is strong. When you are starting out, it feels like something you should be able to do with CSS. Complicating the issue, if you search around for CSS to change/customize scrollbars, you’ll probably find it. The problem is that in IE 5.5, there was proprietary browser extensions to change the look of your scrollbars with attributes like “scrollbar-face-color”. IE 5.5 is long gone, and the concept of allowing that control is CSS is gone with it.
There are situations though, where you will strongly wish you had control over the look of a scrollbar. For instance, when the scrollbar isn’t for the entire browser window. You have a small section on your page that you need to control the height of, but contains content which overflows the container. You may set the overflow of that container to “auto”, and get your default scrollbar. Depending on the design of the site, this scrollbar may look awkward and not at all desirable.
Fortunately, we can harness the amazing powers of JavaScript to solve this problem and give us complete design control over our scrollbars again. The basic theory is that we wrap the scrollable area in a new element with HIDDEN overflow, then we remove the overflow from the inside element letting it be as tall as it needs to be. Then we add a scrollbar of our own devise and watch for mouse events on it. As we drag it up and down, it adjusts the relative top value of the inside container, replicating perfectly the scrolling.
To make things easier on ourselves, we’ll use an already-existing jQuery plugin: jScrollPane.
Tested and it working in Fx3, Safari 4, IE 6. Opera 9.52 was working, but strangely triggered a regular body scrollbar in some cases.
Step 1: The Markup
<body>
<div id="page-wrap">
<div class="scroll-pane">
</div>
<img src="images/bottomshadow.png" alt="" class="bottomshadow" />
</div>
</body>
The only reason we have a pagewrap here is because we are centering our little scrollable area. Since the plugin will wrap that div with a class of “scroll-pane” in another div, any centering we apply to it will just center it inside that new wrap, not to the body itself. So rather than mess with that, we’ll just wrap it again in a page-wrap to do our basic positioning and centering. We can also apply relative positioning to that wrap, which will allow us to place the shadow graphic inside it and absolutely position it exactly where we want it on the bottom.
Step 2: The CSS
* { margin: 0; padding: 0; }
body { font-size: 12px; line-height: 30px; font-family: Georgia, serif;
background: url(../images/clown.jpg) top left no-repeat #fbfbfb; }
#page-wrap { width: 244px; margin: 50px auto; position: relative; }
.scroll-pane { width: 234px; overflow: auto; padding-right: 10px; height: 400px; }
.bottomshadow { position: absolute; top: 375px; left: -47px; z-index: 9999; }
.jScrollPaneContainer { position: relative; overflow: hidden; z-index: 1; }
.jScrollPaneTrack { position: absolute; cursor: pointer; right: 0; top: 0; height: 100%;
background: url(../images/bar.jpg) top center repeat-y; padding: 3px; }
.jScrollPaneDrag { position: absolute; background: url(../images/ball.png) center center no-repeat;
cursor: pointer; overflow: hidden; }
We covered most of the theory here already. Of interest is the jScrollPaneTrack and jScrollPaneDrag. This is where you get you control over what the scrollbar and scroll handle look like. I’ve applied a rather ragged looking line as the track and a small ragged ball as the handle.
Step 3: Activating JavaScript
Typical plugin activation here. Include jQuery on your page, then the plugin, then call the plugins new function with the parameters you need. In our case, the ball is 12px wide, so we need to specify that when calling the function. That’s just how this function rolls.
<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="js/jScrollPane.js"></script>
<script type="text/javascript">
$(function(){
$('.scroll-pane').jScrollPane({
scrollbarWidth: 12
});
});
</script>
Step 4: Considering Usability and Accessibility
When you remove the standard scrollbar in this manner, you are taking away consistency and convention from users. People become so used to user interface conventions like scrollbars that they might gloss right over your customized one not even recognizing it as a scrollbar. That is obviously a problem. You should be darn sure that your scrollbar strongly reads as a scrollbar if you want people to actually use it (the example in this article could be dramatically improved in this regard). I certainly don’t worship Jakob Nielsen (especially his god-awful website), but he has a pretty good article on scrollbar standards and what works and what doesn’t when it comes to custom ones.
Also be aware the standard scrollbars come with some accessibility built in that your new custom ones won’t. Mostly, this plugin approach is solid. With JavaScript off, you’ll just get regular scrollbars. With CSS off, you’ll see all your content just fine. With both turned on, you’ll get your snazzy new scrollbar, but you will lose the ability to scroll down that area using conventional methods (like the scrolling wheel on your mouse).
Just take all of this into consideration before going with a custom approach. I think it can be the right answer in many design situations where an operating system standard scrollbar can ruin a design.
For no reason, it seems that in your example, the scroll wheel doesn’t work, even than on jScrollPane page works fine :)
Anyway, nice trick ;)
Actually… there is a reason :D Mousewheel plugin for jquery is missing :P
Thanks for thr tricks,
Now I will can make the XP / Vista scroll style to seems like OS X?
Interesting article and technique. If used sparingly.
I’m a great believer in giving content space to breathe. If it doesn’t fit in it’s container on a page then it should probably have it’s own page.
Chris, I have a tenuously related question. I usually visit this site using FF on the mac, if I scroll down a page, hit a link, go somewhere else and then click the back button I am always returned to the top of the page regardless of where I was before. But Safari never fails to bring me back to the point on the page where I originally clicked the link. I don’t think the problem is entirely FF because it doesn’t happen on other sites. If you have any idea why this might be I would love to know.
You obviously know the serious usability loss in using your own scroll-bars as such. For this reason, I won’t even consider changing scroll bars. If the project requires me to do so, the project needs to be changed.
Nice article and something I would have considered years ago when changing the scroll bars was “cool”! But now I definitely wouldn’t consider changing them, to me it always looks tacky to have the main scrollbar changed, and as Mike said, the content should have its own page if its container needs a scroll!
It’s good to see JavaScript continue to take features away from flash like this.
I thought styling a scroll bar was a BIG no no in web design… seems kinda pointless to me.
I’ve been looking for this solution for months, and you’ve addressed it and even provided the files I need for my project.
Though I do agree that it should be used sparingly, it can make your scrollable box look amazing!
Thanks Chris.
While you say that Browsers don’t generally style the scroll box, in my version of Firefox, the scroll bars are black. I’m using a custom theme for it – NightLaunch i believe and that seems to control the scroll bars’ styling.
This may be an exception to your statement but if there is a way for doing it through a browser theme which is mainly made up of CSS, then surely there is a way to change the styling for scroll bars with browser proprietary styles?
Just a thought anyway, what do you guys think?
by the way, yet another great post Chris, very informative. I’ll hopefully get around to applying this on some new designs!
Due to the reasons of accessibility ill rather stick with the normal un skinned scrollbar.. I believe its part of the browser skin. And we as web developers have nothing do with that part. If we would, we would have become theme developers..
One of the other cool features in jScrollPane is that you can also include jquery.mousewheel.js and use mousewheel in your scrollable area. It doesn’t support Opera properly, though.
weird. i cant use the space bar or page down to um, page down. it works elsewhere in this site, just not in this article. you broke my computer! hehe
{:firefox 3.0.1; :mac os 10.5.2}
Nice trick.
It’s a real shame there’s no real (as in, no javascript, and with scrolling working) way of doing this via CSS. I believe there is in IE6, using scrollbar-base-color etc though, but that’s no good these days. They’re probably trying to keep scrollbars as uniform as possible, but I think it’d be better to allow people to customize them (just two images really, background and bar).
I don’t think it’s some great sin to co-opt the scroll bar style, especially when one considers the differing widths of the OSX and XP scrollbars (not to mention any other OS). If you’ve got a scrollbar inside the body of your website, an OS default scrollbar can be downright garish. I do agree that I wish there was a CSS-only way of doing this, though.
However, while I’d love to use this trick, I tend to use MooTools more than jQuery. MooScroll performs the same scroll-swapping trick. If anyone else has similar framework preferences, I’d recommend checking it out; I’ve wanted to use it for a while, and finally have a website I can play with it on. :)
Is there a possible way to make the content area scroll horizontally instead of vertically?
Help is appreciated.
Vadim.
thanks for the file. oh yes, congrats on making on the top of delicious.com
keep it up.
Thanks Chris. I don’t see why so many web designers are so uptight about design ‘rules’. Here’s my simple rule: If it looks good, do it. If not avoid using it. Rules are the enemy of innovation.
@Jackie, because most of us earn a living developing sites for clients who have a product/service to sell. Many of these “rules” are here for good reason. The more difficult you make a site to use for someone, the more quickly your chance of getting a conversion diminishes. The user stops focussing on the content and the message and becomes distracted by the interface.
I can think of very few reasons where I’d be willing to change the scroll bars on a site. In most cases I’m loathe to have them anywhere other than flush hard against the right hand edge of the window.
Its fine to have a “plain” scrollbar in the browser window itself, why would you want to change the look of a users browser? Its intrusive, annoying, and people just don’t like it. Why do you think MS dropped it from IE?
However, it makes sense to change the scrollbar if there is a scrollable container inside of your website. You would definitely want it to blend into your website for branding sake. Nothing is worse than having weird looking colors that don’t mesh well with yours placed into your website that you spent weeks designing and coding.
This is nice, but another way to do it is use mootools and the UvumiTools scrollbar plugin. No mucking around in javascript and the mousewheel works out of the box without having to add extra scripts. Plus, its good for people that use other frameworks.
Conversely, you could just drop scrollable containers altogether, but I realize that in some websites it is necessary.
I have another solution. I used this every time i need scrollable areas in my website. It based on mootools and the name is ScrollControll. There is also a second version that work with motools 1.2.
On my side there is a small description but only in german, so here is the exmaple. Try it out and have fun :-)
A few days ago, I noticed a site had used this very technique to customize the scrollbar. It was the first time I’d really noticed that it could be done with CSS and JS.
But the novelty wore off after about 2 seconds and I found myself increasingly annoyed with it because my scrolling wheel on my mouse did not work with it.
I think it’s good for the option to be available, but I am very strongly opposed to it being used on any site that wants my respect. I believe that it’s important for scrollbars as well as form elements to closely match those of the user’s operating system. It’s for that reason that I try to keep modifications to a minimum. The average user can more easily identify elements that are familiar. Design is very important but so is usability.
I’m in no way criticizing you for posting this, I’m just making a general statement that websites should conform to certain standards.
But I’m very appreciative that you posted this script, because I was curious to peek under the hood just to see how it was done. Thanks for that.
Nice work! But what about for 100% width of content area?