Baseline Rules for Scrollbar Usability

Jeff Goldblum saying “Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should.”

Now that one of the most popular CSS resource sites on the innertubes has implemented styled scrollbars in the browser I think the time is right (or too late?) for me to try to capture a starting point for ensuring they are usable.

Having hard rules for usability can be tricky. Conveniently, we can look to inclusive design and accessibility guidelines. After all, in the words of someone else, accessibility is really usability under a microscope.

Generally the feedback I offer applies to desktop browsing. For a touch-only context where the page can be scrolled by a flick anywhere on the screen some of the sizing suggestions need not apply, though visibility suggestions should.

I am intentionally excluding visuals in this post. I do not want my terrible design skills to prejudice your approach.

Web Content Accessibility Guidelines

The Web Content Accessibility Guidelines (WCAG) version 2.1 can help us. What follows are also informed by my experience and opinions.

Bear in mind this frustrating part. If you leave native features alone then you can usually get a pass in an accessibility audit. Just like the browser’s default focus ring does not meet WCAG contrast requirements, the browser’s default scrollbar has its own issues. But once you start changing the browser defaults your page falls under WCAG and you are on the hook for making it comply.


WCAG 2.1 Success Criterion (SC) 1.4.11 Non-text Contrast provides some guidance here. User interface components, including browser controls modified by the author, fall under this. It defines a minimum contrast ratio of 3:1 with adjacent colors.

In this case, I take adjacent to mean the scrubber (scrollbar-thumb), the scroll track (scrollbar-track) and the page. That essentially means they should each have at least a 3:1 contrast ratio with each other.

We should consider taking this further given the importance of this control. The WCAG SC above is Level AA, which is the baseline for most laws that incorporate WCAG. The corresponding AA SC for text contrast sets a minimum of 4.5:1. There is a text contrast SC at Level AAA, or the strictest level designed to support the broadest range of users, that defines a minimum 7:1 contrast ratio.

It may be worth defining a minimum baseline contrast for you own styles. Perhaps 3:1 between the track and the page and 4.5:1 between the scrubber and the track. If users choose a higher contrast mode then kick it up to 4.5:1 for the page/track and 7:1 for the track/scrubber.

Target Size

WCAG provides for the target size of controls, and while the browser controls are normally exempted the very fact that you plan to modify them means it applies here. SC 2.5.5: Target Size defines the hit area (the target) as a minimum 44 by 44 CSS pixels.

The target size SC is Level AAA, meaning it is not covered by the assorted laws that incorporate WCAG and is generally considered a nice-to-have. This is partly a function of backward-compatibility with patterns extant on the web (which would make many fail immediately). However, platform UI guidelines already have their own recommendations that generally match.

Apple recommends hit areas of 44pt × 44pt. Microsoft recommends 48px × 48px (spaced 2mm apart). Android design guidelines recommend 48 × 48 device pixels (spaced 8dp apart). Similarly, the BBC mobile accessibility guidelines recommend 7mm × 7mm (inside an exclusion zone of at least 7mm × 7mm).

Scroll bars are a bit trickier. The height of the scrubber reflects the size of the current viewport in relation to the entire page. A very long page can have a very short scrubber. We should not try to override that as it provides a valuable cue to users. But it also means getting the width right is even more important.

Consider setting a minimum width for the scrollbar and basing its width on units that scale when the user zooms the page. In other words, maybe do not use exclusively vw units. Consider leaning on ems so the scrollbar scales with the page. If a user needs to zoom to see the content then the user might need to zoom to operate the content. Something like calc(44px + .25em) might be a good starting point.

Related, probably avoid media queries based on width or height to adjust the sizing. The risk is that you make it smaller when the user is zoomed, not in a tiny window, and end up making the user’s attempt to fix it futile.

Inclusive Design Principles

The Inclusive Design Principles were put together by a team of smart people and outline same basic rules for putting users first, regardless of their circumstances. They can help inform some other decisions you can make.

Provide a Comparable Experience

Ensure someone who may be color-blind or low vision can still make sense of and use the scrollbars. If the user switches to a high contrast mode or inverted mode, make sure you support that as well.

Consider the Situation

Remember that people may be using the interface in a park, or with their finger instead of a mouse, or while bouncing on a train. Or maybe in a plane during turbulence with a sketchy trackpad and half the screen lit by the sun from the window across the aisle.

Be Consistent

Follow existing conventions. Make the scrubber look like a grabbable / operable control. At a glance, a two-screen-tall page can leave a user wondering if the track is the scrubber. Similarly, an inset border on the scrubber or the track can be confusing because that’s not how scrollbars look.

Give Control

If a user zooms the page, let the scroll bar zoom with it. Maybe even give the user the option to zoom the scroll bar as a site preference. Consider offering the ability to disable your custom scrollbar altogether.

Offer choice

This generally refers to offering different ways to complete tasks. Scrollbars are pretty straightforward, so just make sure you don’t break the ability to use Space to scroll a screenful, or arrows to scroll bit by bit. CSS cannot break this interaction on its own today, but new techniques may emerge that can.

Prioritize Content

People are not on your site to see your nifty scrollbar. They want to read some content or complete a task. Do not distract them.

Add Value

Ask whether your custom scrollbar is really adding value for the user, or if it is just showing off. The latter does not mean you should not do it, but remember who your users are.

Manage Expectations

This is my own rule for interfaces. Users should be able to tell almost at a glance what a control is, what it does, what its current state is, and how to operate it.


Pay attention to how a native scrollbar operates. Often the track is obvious and scrubber has enough contrast. Note that the scrubber generally has a hover style. Sadly, browsers do not currently support a hover style on the scrubber, but it may be worth pushing to get that support and even pre-emptively coding it.


Some platforms will hide the scrollbar until the mouse approaches it. If a user has enabled that setting, you cannot detect it. Either way do not make it disappear using your own custom styles because you prefer it.


If you follow all the suggestions here you might end up with a big, ugly block on the side of your page or overflowing content area. Consider it your starting point that supports the broadest range of users. From there perform some user testing to see what works, what doesn’t, and what can be tweaked.


We have been down this road before, but we seem to keep forgetting.

I am not kidding when I say that I have started and abandoned 5 blog posts over the years (dating back to 1999) that deal with the usability of custom scrollbars. I drafted one on Internet Explorer 5.5’s scroll styles feature, I drafted one when Flash was taking over the web, I drafted one when -webkit prefixes to style scrollbars were announced, and again when people started experimenting with them. But they all lacked useful advice. I hope this post has at least provided that.

CSS Scrollbar Module (added 10 December 2021)

The W3C CSS Scrollbars Styling Module Level 1 is currently a Candidate Recommendation. It touches on the WCAG concerns I raise above and also includes this nugget of truth:

Note: Exposing the scrollbar-related ::-webkit- prefixed pseudo-elements to the Web is considered a mistake by both the CSS Working Group and Webkit.

The module outlines two new properties, scrollbar-color and scrollbar-width.

scrollbar-color takes two values, one for the thumb and one for the track. You could also use auto for one or both. The following warning is included:

When using scrollbar-color property with specific color values, authors should ensure the specified colors have enough contrast between them. For keyword values, UAs should ensure the colors they use have enough contrast. See WCAG 2.1 SC 1.4.11 Non-text Contrast [WCAG21]. UAs may ignore these contrast requirements based on explicit user preferences (for example, when users choose a configuration option/setting that always ensures a particular scrollbar color / use of system default scrollbars).

scrollbar-width accepts two values (besides auto): thin and none. There are notes that hiding scrollbars can be a problem for mouse users, and that scrollbars should not be thin except for cramped cases.

The scrollbar must nonetheless remain wide enough to be usable. (Implementers may wish to consult WCAG 2.1 SC 2.5.5 Target Size. [WCAG21])

The document puts some burden on User Agents to not allow developers to make broken pages, and counsels developers to follow WCAG. However, experience has shown that if you are not already factoring scrollbars into your WCAG testing, it is likely only a matter of time before you will need to.

WCAG 2.2 (added 9 June 2022)

It seems more and more likely that in the proposed WCAG version 2.2 the new success criterion 2.5.8 Target Size (Minimum) will come through in its current form. And it will be at Level AA.

2.5.8 allows for a smaller minimum target size, 24 × 24 CSS pixels, or an offset of 24 pixels to adjacent targets. My take is that if you make your scrollbars smaller than 24 CSS pixels in width, you will then have to ensure they are never at least 24 CSS pixels away from the nearest target. I am oversimplifying a bit, but you can read more details and get a 24×24 pixel cursor bookmarklet I made specifically to aid testing.

Update: 8 May 2023

Eric Bailey has gone further than I and simply said Don’t use custom CSS scrollbars. If the post you just read was not clear, I agree.

His post hits the same broad strokes I do above — contrast, target size, theming, preferences. He is simply more overt in stating not to mess with it. Eric links to another post I do not, Blake Watson’s Neglecting the scrollbar: a costly trend in UI design from just a couple months ago.

Incidentally, I finally installed Stylus because the scrollbars in the default Mastodon UI have such terrible contrast that I opted to override them. If you are familiar with Mastodon and its leader’s overall failure to incorporate accessibility best practices, this should not surprise you. Installing Stylus also made it easier to fix some other problems on the site. So well done, Mastodon, your terrible scrollbars broke my Stylus resistance.



As most browser scrollbars don’t meet WCAG 2.1 by default, an interesting way to look at this alternately would be to improve on what users are getting by default with their browser. In essence, make scrollbars meet the standard.

Showing some examples of well executed accessible scrollbars would make for a nice article.

In response to GM. Reply

In general, native UI elements get a default pass in WCAG. This not a statement of whether or not I agree with it.

To your point, if I ever find well executed scrollbars it would indeed make for a nice post.


Per CSSWG, authors shouldn’t control scrollbar width. Let the OS and browsers work that out. (I’m paraphrasing from getting dunked on here:

Paul Grenier; . Permalink

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>