Surfin’ Safari

Styling Scrollbars

Posted by Dave Hyatt on Thursday, March 19th, 2009 at 2:19 pm

WebKit now supports styling of the scrollbars in overflow sections, listboxes, dropdown menus and textareas. For those who want to skip the article and just go right to the source, here is an example:

Scrollbar Example

Here is a screenshot for those not running a recent enough WebKit:

The scrollbar pseudo-element indicates that an object should use a custom scrollbar. When this pseudo element is present, WebKit will turn off its built-in scrollbar rendering and just use the information provided in CSS.

::-webkit-scrollbar {
    width: 13px;
    height: 13px;
}

The width and height properties on the scrollbar element indicate the width of the vertical scrollbar and the height of the horizontal scrollbar. Percentages can be specified for these values as well, in which case the scrollbar will consume that percentage of the viewport area.

A scrollbar consists of scrollbar buttons and a track. The track itself is further subdivided into track pieces and a thumb. The track pieces represent the areas above and below the thumb.

In addition the scrollbar corner can now be styled, as well as the resizer used by resizable textareas.

Here is a complete list of all the new pseudo-elements. All of these pseudo-elements must be prefixed with -webkit-.

scrollbar
scrollbar-button
scrollbar-track
scrollbar-track-piece
scrollbar-thumb
scrollbar-corner
resizer

Each of these objects can be styled with borders, shadows, background images, and so on to create completely custom scrollbars that will still honor the settings of the operating system as far as button placement and click behavior.

The following pseudo classes have been introduced and can be applied to the pseudo-elements.

: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.)

In addition the :enabled, :disabled, :hover and :active pseudo-classes also work with scrollbar pieces.

The display property can be set to none in order to hide specific pieces.

Margins are supported along the axis of the scrollbar. They can be negative (so that the track can for example be inflated to cover the buttons partially).

The linked example above provides a very complex scrollbar that has all of the OS X scrollbar behaviors (double buttons, an inactive look, track overlapping the buttons, etc.) as well as many of the Windows Vista scrollbar behaviors (hover effects, unique pressed looks above and below the track, etc.).

19 Responses to “Styling Scrollbars”

  1. 5040 Says:

    Useful addition in some cases. I suggest making it resolution independent, so it will keep it’s detail when zooming a page.

  2. hawkman Says:

    Intriguing. Part of me rejoices at the thought of being able to further immerse the user in the page design; and part of me is screaming in horror at the thought of all the ways this is going to be abused. It’s undeniably nice work, though.

  3. Jamescat Says:

    @5040:

    The feature uses images to provide the custom look of buttons and other controls. One would presume that SVG elements would be the way to provide resolution independence. The example uses PNG, which are obviously not capable of being scaled up any better than other image format.

    Of course, I would also assume (until SVG backgrounds work — hopefully they will, right guys?) you could use larger than necessary images (say 2x or 4x or even 10x the required size) and scale them down using -webkit-background-size for “normal” resolutions and let the browsers scale them back up with the rest of the window elements as necessary based on user preferences.

    Obviously, this is not as desirable as SVG backgrounds would be… particularly when considering page load time / size… but it should work — Well, at least, I think. ;-)

  4. James_Roe Says:

    Interesting, IE has had hacked support for scroll bars for a while.

    http://www.htmlgoodies.com/beyond/css/article.php/3470421

    When I say hacked I of course mean HACKED. No image support, etc..

    I recently implemented stylized scroll bars using this jquery package.

    http://code.google.com/p/jscrollpane/

    It works in ie6/7/8, safari, chrome, iphone safari, and ff. Apparently support is bugged on Blackberries though.

    http://dotroe.com/subpage.html

    I could have built active state into the scroll bars as well, but had frankly hit the end of what I was interested in doing with it.

    Glad to see that browsers are starting to provide css based support for scroll bars though, they can frequently be useful if you want to have content in a menu for instance fit in a limited space. Until recently your only realistic option was flash, and while the JS solutions work it will be nice to be able to just offload that into css in the future.

  5. coolfactor Says:

    Just the other day, I was looking for how to style scrollbars to fit with my client’s website design. I didn’t realize it wasn’t supported in non-IE browsers yet, so you can imagine my surprise by seeing this be announced. Now, seeing as it’s only in WebKit nightly, that doesn’t really help me out, but it’s a sure sign of progress in the direction I need.

    But wow, the syntax! Not easy on the eyes. Is that double-colon syntax standard in CSS 3 as a scope operator? First time I’ve seen that.

    @hawkman — I share your sentiment about how this feature can be abused, indeed, but realistically, many that would abuse it usually went down the Flash path, allowing them to do it anyway.

    @James_Row — cool solution! A jQuery plugin. I’m checking that out. Thanks!

    Keep up the great work, WebKit team. The development world is a better and more fun place again because of your commitment and efforts.

  6. coolfactor Says:

    This doesn’t appear to target the parent window scrollbar. Will that be coming? I expected that to be be supported already using something like this:

    This would target *all* scrollbars, including the parent window.
    ::-webkit-scrollbar

    This would target only scrollbars on div elements
    div::-webkit-scrollbar

    This would target a div with class of “scrollable”
    div.scrollable::-webkit-scrollbar

    Am I on the right track, or is just the global ::-webkit-scrollbar supported right now? It would also be cool to be able to group styles, say using the @ operator:

    @div.scrollable {
    ::-webkit-scrollbar {

    }
    }

  7. vitch Says:

    Interesting stuf. jScrollPane is my jQuery plugin solution to this which some people have already mentioned:

    http://www.kelvinluck.com/projects/jscrollpane-custom-cross-browser-scrollbars/

    I’ll be studying the webkit approach to the problem and will see if there are elements that I can add to my plugin to improve it.

    Thanks!

  8. Patrick Geiller Says:

    (Nitpicking)

    * In a non styled crossbar, holding the mouse down on an arrow then moving onto the other arrow reverses the scrolling direction. In a styled crossbar, scrolling stops.

    * In a non styled crossbar, scroll speed increases the longer you keep scrolling. In a styled crossbar, scroll speed remains constant.

  9. oscargodson Says:

    Please don’t do this, please. This has to be one of the biggest UI mistakes of all time. UI design 101, don’t change the window chrome. It’s like IE scroll bars 2.0.

    Don’t get me wrong, this is very “cool”, but should never be used in an sensible design ever.

  10. Ahruman Says:

    What oscargodson said, with bells on.

    In addition to that, the most noticeable things about the example are that a) you have to wait for your scroll bar elements to load before you can interact with the page properly (providing nostalgic flashbacks to the web of a decade ago), and b) the vertical scroll bars consistently fail to display properly (in Safari 4/5528.16 and WebKit r41944 under OS X).

  11. Thomas Winwood Says:

    Why are you trying to standardise a set of pseudoelements and pseudoselectors to style bits of UI chrome when there isn’t even a standard for rendering UI chrome inside browsers to begin with?

    The HTML 4 standard explicitly leaves it up to the UA how to style form elements; the application of CSS attributes to these elements is left undefined. Until there’s a definite standard used by the majority of browsers for rendering form elements, I’m not sure it’s wise to incorporate CSS styles for these form elements. Styling these with the UA-proprietary prefix is just admitting that there’s no real merit to this addition.

  12. zzzombie Says:

    Too bad it can’t style windows scrollbars.
    I’m coding something that uses 2 vertical frames, and the scrollbar at the middle of the window is way too flashy, I was hoping these new CSS properties would help… well it doesn’t :-/
    Anyway, i like this new feature.

  13. starfruitman Says:

    Yeah I am also on the fence whether you should add “styles” to browser chrome elements. It really goes against usability guidelines everywhere regarding giving visitors a consistent experience on the web. If every web site did it, egadds I dare to ponder that !

  14. Vasil Dinkov Says:

    I also find this “cool” but I do believe it’s not a good idea to go on with it as it can potentially cause usability issues to many users if some authors don’t make good use of the feature. BTW, the current implementation has not taken care of the case when images are disabled.

  15. Ölbaum Says:

    That’s all very nice and flashy. Next, can we have Safari send a proper Accept-Language header? That would be lovely.

    For the record, my languages in the International preference pane are set to English, French, German, yet only en-us is sent in the Accept-Language header. It means that on most web sites designed for Switzerland that are available in German, French and Italian, the server, seeing it (seemingly) can’t provide any of my preferred language(s), default to German. With a proper header (e.g. en,fr;q=0.7,de;q=0.3), it would serve me French content.

    I’m pretty sure it’s not the right place to report this, but hey, I also sent it using the ad hoc Safari menu command, several times is the past few years.

  16. thinsoldier Says:

    … people keep nagging about making fonts resizable (em or %) for the benefit of the elderly… well my grandma has trouble accurately clicking the scrollbars… I wanna make the scrollbars FAT and CHUNKY… DO IT FOR MY GRANDMAAAAA!!!! (and the 4-year-olds!)

  17. Trackback from my blog:

    check this out…

    this is mine…

  18. Abhi Beckert Says:

    oscargodson Says: “Don’t get me wrong, this is very “cool”, but should never be used in an sensible design ever.”

    That depends entirely on the website! For example if you have a black website, say a photo gallery, and want scroll bars embedded in the middle of the page (not part of the window chrome), then you should have dark coloured scroll bars. White and candy blue will clash horribly and distract from the content on the page.

    For example, MobileMe uses black scroll bars in it’s photo gallery. They’re using javascript, and so don’t function as other scroll bars do. This commit can be used to fix that problem.

  19. Tab Atkins Jr Says:

    … people keep nagging about making fonts resizable (em or %) for the benefit of the elderly… well my grandma has trouble accurately clicking the scrollbars… I wanna make the scrollbars FAT and CHUNKY… DO IT FOR MY GRANDMAAAAA!!!! (and the 4-year-olds!)

    Under Windows you can change the thickness of scrollbars system-wide by going to Display Properties -> Appearance -> Advanced -> Scrollbar. Change the size to whatever you want. I imagine you can do something similar under Mac.

    That’s the correct way to adjust these things. If the user has a problem with scrollbars, they’ll have problems *everywhere*, and the OS should correct it. “Fixing” is on a single site doesn’t really help anyone, and is actively bad for people with normal eyesight and motor skills.