Way back in the day, you could customize scrollbars in IE (e.g. v5.5) with non-standard CSS properties like scrollbar-base-color
which you would use on the element that scrolls (like the <body>
) and do totally rad things. IE dropped that.
These days, customizing scrollbars is back, but it’s WebKit this time. It’s a bit better now, because the properties are vendor-prefixed (e.g. ::-webkit-scrollbar
) and use the “Shadow DOM“. This has been around for a couple of years. David Hyatt blogged it in early 2009.
The Goods
The Different Pieces
These are the pseudo-elements themselves. The actual parts of the scrollbars.
::-webkit-scrollbar { /* 1 */ }
::-webkit-scrollbar-button { /* 2 */ }
::-webkit-scrollbar-track { /* 3 */ }
::-webkit-scrollbar-track-piece { /* 4 */ }
::-webkit-scrollbar-thumb { /* 5 */ }
::-webkit-scrollbar-corner { /* 6 */ }
::-webkit-resizer { /* 7 */ }
The Different States
These are the pseudo-class selectors. They allow for more specific selection of the parts, like when the scrollbar is in different states.
:horizontal
:vertical
:decrement
:increment
:start
:end
:double-button
:single-button
:no-button
:corner-present
:window-inactive
I’m going to steal this whole section from David’s blog post on the WebKit blog because it explains each part well:
:horizontal – The horizontal pseudo-class applies to any scrollbar pieces that have a horizontal orientation.
:vertical – The vertical pseudo-class applies to any scrollbar pieces that have a vertical orientation.
:decrement – The decrement pseudo-class applies to buttons and track pieces. It indicates whether or not the button or track piece will decrement the view’s position when used (e.g., up on a vertical scrollbar, left on a horizontal scrollbar).
:increment – The increment pseudo-class applies to buttons and track pieces. It indicates whether or not a button or track piece will increment the view’s position when used (e.g., down on a vertical scrollbar, right on a horizontal scrollbar).
:start – The start pseudo-class applies to buttons and track pieces. It indicates whether the object is placed before the thumb.
:end – The end pseudo-class applies to buttons and track pieces. It indicates whether the object is placed after the thumb.
:double-button – The double-button pseudo-class applies to buttons and track pieces. It is used to detect whether a button is part of a pair of buttons that are together at the same end of a scrollbar. For track pieces it indicates whether the track piece abuts a pair of buttons.
:single-button – The single-button pseudo-class applies to buttons and track pieces. It is used to detect whether a button is by itself at the end of a scrollbar. For track pieces it indicates whether the track piece abuts a singleton button.
:no-button – Applies to track pieces and indicates whether or not the track piece runs to the edge of the scrollbar, i.e., there is no button at that end of the track.
:corner-present – Applies to all scrollbar pieces and indicates whether or not a scrollbar corner is present.
:window-inactive – Applies to all scrollbar pieces and indicates whether or not the window containing the scrollbar is currently active. (In recent nightlies, this pseudo-class now applies to ::selection as well. We plan to extend it to work with any content and to propose it as a new standard pseudo-class.)
All together now
These pseudo elements and pseudo class selectors work together. Here are some random examples:
::-webkit-scrollbar-track-piece:start {
/* Select the top half (or left half) or scrollbar track individually */
}
::-webkit-scrollbar-thumb:window-inactive {
/* Select the thumb when the browser window isn't in focus */
}
::-webkit-scrollbar-button:horizontal:decrement:hover {
/* Select the down or left scroll button when it's being hovered by the mouse */
}
Very Simple Example
To make a really simple custom scrollbar we could do this:
::-webkit-scrollbar {
width: 12px;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
}
In which we’d get this on a simple div with vertically overflowing text:
In The Wild
Check out the very subtle and nice scrollbars on Tim Van Damme’s blog Maxvoltar (Update September 2012: Tim’s site no longer uses this design):
The particularly nice bit here is that the scrollbar is on the body element, yet the scrollbar isn’t stuck to the top, bottom, or right edge of the browser window as scroll bars normally are. I made a test page with copy-and-pasteable code to achieve that a similar effect:
On Forrst, they use custom scollbars on code snippets which are also pretty nice. They are less visually intense and so don’t fight as much with the code highlighting.
Related
- Dion Almaer has a useful little “debug” page for scrollbars with all the parts in bold colors to see what’s what. (from this article)
- Similar article on Beautiful Pixels.
- Google Wave went kinda overboard with them back when that was still a thing.
Nice, but style.css … 404 ;)
Max Voltar websites works in Chrome.
That is not the case for your example.
Same here with Chrome 10.
It works fine for me in Chrome 10.
Nice trick, definitely adds a nice touch for websites.
Works fine in Chrome mate.
thanks
What if I wanted to show custom scroll bars on non-webkit browsers?
You’d either:
1) Not. Or,
2) Google up some JavaScript based solution.
If your truly desperate Flash or JavaScript (somehow, but not any way that I know of).
I can’t replicate in Chrome 11 or Safari 5 mac.
I have used the plugin at the link below before, it works fairly well. Its not the method Chris uses above, but its a decent JS based plugin.
http://www.kelvinluck.com/assets/jquery/jScrollPane/jScrollPane.html
Sul
Yet another timely article Chris!
The point about this not working in other non-webkit browsers is sadly true – I’ve recently spent quite a while trying to figure out a solution to this specifically for use within text areas.
There are a few javascript/jquery solutions out there and probably one of the best I’ve found was JScrollPane.
As for text area solutions I’m afraid I didn’t unearth too much but I’m determined to try and figure something out for that too!
Great post Chris, thanks a lot!
Rumor has it, OS X Lion coming out this year is supposed to get rid of the shiny liquid blue scroll bars in OS X anyway. They’re apparently adopting a flat, gray, iOS feel. Like you said, the blue “thumbs” really shout for attention. That’ll be a welcome improvement.
Your demo is broken in both Chrome and Safari OSX.
That’s because I’m an idiot. Fixed. Burying.
any hint on a possibility that this will become available on other browsers? even on IE i hope :)
IE supports styling the scrollbar for years already:
body {
scrollbar-face-color: #eee;
scrollbar-highlight-color: #fff;
scrollbar-3dlight-color: #ccc;
scrollbar-darkshadow-color: #fff;
scrollbar-shadow-color: #aaa;
scrollbar-arrow-color: #000000;
scrollbar-track-color: #eee;
}
source:
http://www.computing.net/answers/webdevel/how-to-change-scroll-bar-look/740.html
Just the color though
Pity this type of overflow doesn’t work on iOS… any idea on how to enable touch events?
I’ve had the same problem, but figured out that @media querys can help.
@only screen and (max-device-width:480px){
//Insert your Scrollbar-CSS her //
}
Works for me.
Please delete that last comment. Must have been on crack or something
Or Chrome used a cached version.
Hi Chris, thanks for this, I really loved it and tried it in my project right away!
I hope -moz- comes after this soon, it can make the design more unique, I’d always wanted this and I saw a few flash scrolbars that was awesome in look but creepy in format, ha! but CSS3 is very exciting… and I would love to use it.
A couple of things I would like to point out…
As we know it doesn’t work properly until you put position: absolute; in the body section. If we do the right: 20px; it will look fine only for -webkit- browsers! If you see this in Mozilla for example, it will look non-standard and a bit confusing to the user… So I set the right: 0; to level things out. (If you know a better way please let me know, I like to have it 20px to the left)
Another thing is about the .body again, we better set top and bottom 0 in order to have the page full in height and replace it with margin in the:
::-webkit-scrollbar-track { margin: 20px 0; }
Is it me or you can’t use the mouse wheel in your example?
Mine works to scroll down, but not up.
Scratch that! It works Up but not Down.
How about fixing broken features in webkit rather than introducing new ones!
i.e. the fact that the cursor style on an area tag is never honored in webkit..
sheess….
Is this broken? I haven’t seen any problems yet. I haven’t tried to do a ton of advanced stuff though. I’d think the most broken part is that isn’t a little unclear and undocumented about what properties the different parts will accept.
Regarding the area bug, I hadn’t heard of that, but does sound buggy. Best thing to do of course, is to create a reduced test case and submit as a bug (http://www.webkit.org/quality/reporting.html) If it’s already been reported, submitting your test case will still be helpful in that it’s all the more material to test and registers more interest in the problem.
Here’s a good collection of premade scrollbars. One looks like the iTunes scrollbars (marble) and the other is basically just a dark version of that. The download links are broken, but I found the actual downloads. Marble Black.
Don’t forget Opera that can do some tweaks to scrollbars since many years as well. I used it on my website, 6 years ago.
scrollbar-face-color:
scrollbar-highligh-color:
scrollbar-shadow-color:
scrollbar-3dlight-color:
scrollbar-arrow-color:
scrollbar-track-color:
scrollbar-darkshadow-color:
Not as good as the implementation of Webkit but then, if you want to play with it.
Is it possible to place an image on the scroll bar?
I’ve used Malihu’s jquery plugin on this website http://bitteart.dk/ to horizontally scroll a client’s gallery. It works pretty well in all modern browsers (I didn’t check in old browsers).
Plugin page: http://manos.malihu.gr/jquery-custom-content-scroller
This is very old method…
Here is the new one and also customize your own scrollbars…
http://www.hesido.com/web.php?page=customscrollbar
wow nice tuts never tought it easy as find here .. :)
Wth is wrong with this website? All text is unreadable in all my browsers. Please use a proper font, or at least fallback to something readable.
Hi, may i say something : there are usually some really good stuff with css3 but it’s usually the same : only webkit or ‘only’ mozilla, like text-transform or the scrollbar custom here. So, what do we’re supposed to do with it, wait for 2 years that the concept arrives in every browser…? thanks for the tip anyway, good stuff…for webkit browsers
Ones again you amaze me with your findings and tutorials.. thanks for a great website Chris
Webkit scrollers was a part of my personal blog since mid-2010 (I removed it few time back). Nice article Chris.
Can’t get it to work on FF4, the example doesn’t work either
See title of article.
Thanks for the mention, Chris! If only every browser supported this stuff. In time, I suppose.
Kyle
Oh god no. This could be the worst thing in webkit! Scrollbars are the same in every app… if you changed the look of them the average person wouldn’t have a clue what they were.
Could be terrible for usability.
Do you have any research on that?
I know what you mean. Standard looks are familiar to users, they’ve used them before, so they know how to use them again.
But these customizations aren’t totally reinventing the concept of a scroll bar. They still basically look like scrollbars if you do it right. I’d wager most users scroll with a mouse motion of some kind, in which case they’d see this custom scrollbar scroll and get it right away.
But now that’s just me speculating.
Yeah, was speculating too. The only thing I was going on was that changing user expectations has always proved to be a bad thing (only read that from nielsen’s papers).
Thing about a scroll wheel is that it scrolls depending on where your cursor is. If you don’t know that something has scrollable content a non-techy user could easily get annoyed at their mouse/trackpad.
What do you reckon?
Also, sorry mate, I didn’t mean to sound rude! It looks like a really cool trick for what it does, thanks for sharing!
I love the custom scrollbars but is there a way to resolve how the browser window must be clicked before the keyboard up/down arrays scroll the page? That is kind of a deal breaker.
I think these are really cool, especially the usage on Forrst on code examples, which to me look pretty ugly with Apple aqua scrollbars or something like that.
I have to agree with most of the commenters over at HN (http://news.ycombinator.com/item?id=2513578) that styling scroll bars is usually a bad idea.
As “stuk” said over there: “The problem with allowing the customisation of scrollbars is that most people are going to make them worse.”
Indeed.
Great article, I been into web development with HTML and CSS for a year now, so Im pretty new to all this stuff but it feels nice having access to information like this one so well explained.
As many said its a petty that this only works on webkit.
Thank you Chris for the awesome stuff here!
This Is What I Have Been looking for over like 6 months, Thanks a lot… just one question how to i change the color from red to like a dark gray
Thanks, In Advanced
With this, “background-attachment: scroll” doesn’t work. It is because of “overflow-y: scroll” in the “body”… Any solution?
I just noticed that I can only use solid colors for the scrollbars in Chrome 11.0.696.65 on Mac. I had to remove all of the rgba calls for Chrome to function. Otherwise, made a semi-transparent hole in the browser that tried to render my desktop background… kind of strange.
There is also a bug in webkit whereby scrollbars won’t appear on an iframe: http://code.google.com/p/chromium/issues/detail?id=57292
If you are using any type of scroll event listener, be aware that once you style the scrollbar, it is removed from the normal webkit DOM and is no longer selectable via javascript (or jQuery) – at least, that’s what I have found thus far.
For example, comment out the -webkit-scrollbar styles in the demo and bind a scroll trace to window ::
$(window).scroll(function() {
console.log($(window).scrollTop(),$(window).height());
});
Then un-comment the -webkit-scrollbar styles and you will find that the scroll event listener is no longer triggered. Changing the bind event to “body” will trigger the scroll event listener but scrollTop will be fixed to 0 and height will be fixed to the visible window’s height. I get similar results when I trace $(“html”).scrollTop(); or $(“body”).scrollTop(); from within the event.
Even though you can see (in the web inspector) that the scrollbar is attached to the html tag, I have not been able to find a valid selector with which to recapture these values. I even tried selecting the $(“::-webkit-scrollbar-track-piece”) object but alas, no.
hi, isn’t this kind of what everyone is looking for and is it workable in all browsers? The website is in french which means i can’t read it but the scroll bar works quite swell for such a small amount of code, and i haven’t used it so i can’t tell what its drawbacks would be . . . Anyone willing to take a look at it?
http://carotut.voila.net/tutoriel/scrollbar_en_images/index.htm
thats the link! do reply as I’m not using it till someone answers one or more of my queries above
Nice and clear solution thx
not working in firefox
See title of post.
Not working in firefox
SUPER AWESOME post! #thanks
Is it possible to overlay the scrollbar over content? The desired effect would be to fix the “shift” problem where some pages do not require a scrollbar. It would be nice if we could make the scrollbar sit on top of the “content” (actually just a blank gutter in my case) instead of pushing the site to the left.
http://aokp.co is a good example of this.
Hi friends,
if I use this code
::-webkit-scrollbar {
width: 12px;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
}
it get apply on all the scrollbars, how can i apply it to a particular div ??????
Hey, nice tutorial :-)
But i’ve got a question: how do you realize this margin from your right border in your example (with the red scroll thumb)?
I tried using it at -webkit-scrollbar-thumb (with
margin: 30px
), also at -webkit-scrollbar and body, but the scrollbar is everytime atright: 0px
.Can you help me?
works only in chrome :(
buddy, so now how make custom scrollbars in FF and IE ??
Hey it’s working fine and cool :)
How can reduce the thumb height?
hey its working in chrome only :( so how can i make custom scrollbars in firefox nd IE
It’s not working in firefox…
Burying, because this has already been covered. (See the title of the article).