The Current State of Styling Scrollbars in CSS (2022 Update)

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Your best bet for styling scrollbars in CSS, for as much cross-browser support as possible, is to use the special ::webkit prefixed scrollbar CSS properties (Chrome & Safari will need those for now) and the standardized scrollbar-width and scrollbar-color properties (for Firefox for now).

So a basic setup would look like this:

.styled-scrollbars {
  /* Foreground, Background */
  scrollbar-color: #999 #333;
}
.styled-scrollbars::-webkit-scrollbar {
  width: 10px; /* Mostly for vertical scrollbars */
  height: 10px; /* Mostly for horizontal scrollbars */
}
.styled-scrollbars::-webkit-scrollbar-thumb { /* Foreground */
  background: #999;
}
.styled-scrollbars::-webkit-scrollbar-track { /* Background */
  background: #333;
}

Using Custom Properties for Styling Scrollbars in CSS

You could DRY that up a bit with Custom Properties, like:

.styled-scrollbars {
  --scrollbar-foreground: #999
  --scrollbar-background: #333
  /* Foreground, Background */
  scrollbar-color: var(--scrollbar-foreground) var(--scrollbar-background);
}
.styled-scrollbars::-webkit-scrollbar {
  width: 10px; /* Mostly for vertical scrollbars */
  height: 10px; /* Mostly for horizontal scrollbars */
}
.styled-scrollbars::-webkit-scrollbar-thumb { /* Foreground */
  background: var(--scrollbar-foreground);
}
.styled-scrollbars::-webkit-scrollbar-track { /* Background */
  background: var(--scrollbar-background);
}

A Sass Mixin & Other Preprocessing Options

If you’re using Sass, you could abstract the usage like this, allowing for customization parameters:

@mixin scrollbars(
  $size: 10px,
  $foreground-color: #999,
  $background-color: #333
) {
  // For Chrome & Safari
  &::-webkit-scrollbar {
    width: $size;
    height: $size;
  }
  &::-webkit-scrollbar-thumb {
    background: $foreground-color;
  }
  &::-webkit-scrollbar-track {
    background: $background-color;
  }

  // Standard version (Firefox only for now)
  scrollbar-color: $foreground-color $background-color;
}

You might think Autoprefixer could help deal with the vendor prefixing situation, but the syntaxes are so different that it doesn’t look like they are terribly interested and I don’t blame them.

If you are into the PostCSS thing, there is a postcss-scrollbar plugin though. The idea is that you write the standardized syntax and it makes the vendor prefixes versions to match. Meaning you’re limited in styling choices to what the spec provides, but that’s probably a smart move long-term anyway.

/* input */
.scrollable {
  scrollbar-color: rebeccapurple green;
  scrollbar-width: thin;
}
/* output */
.scrollable::-webkit-scrollbar-thumb {
  background-color: rebeccapurple;
}
.scrollable::-webkit-scrollbar-track {
  background-color: green;
}
.scrollable::-webkit-scrollbar-corner {
  background-color: green;
}
.scrollable::-webkit-scrollbar {
  width: 0.5rem;
  height: 0.5rem;
}
.scrollable {
  -ms-overflow-style: auto;
  scrollbar-color: rebeccapurple green;
  scrollbar-width: thin;
}

More Exotic Chrome & Safari Scrollbar Styles

The non-standard ::-webkit- properties for styling scrollbars in CSS have much more styling possibility than the standardized properties. For example, I could make the width of a vertical scrollbar extremely wide, make the background track have inset shadows, and the foreground thumb have a gradient:

Here are a bunch more fancy styles that use the vendor-prefixed approach:

There are loads of them on CodePen to browse.

A JavaScript Approach to Styled Scrollbars

If styled scrollbars are a necessity and you need very detailed design control perfectly across browsers, then you’ll probably have to reach for a JavaScript solution. There must be dozens of libraries for that. I ran across simplebar and it looks like a pretty modern one with easy instantiation. Here’s a demo of that:

Here’s another one called simple-scrollbar:

Das Surma did a very fancy tutorial that creates a custom scrollbar that doesn’t actually require any JavaScript when scrolling (good for perf), but does require some JavaScript setup code.

Custom scrollbars are extremely rare and that’s mostly due to the fact that scrollbars are one of the remaining bits on the web that are pretty much unstylable (I’m looking at you, date picker). You can use JavaScript to build your own, but that’s expensive, low fidelity and can feel laggy. In this article, we will leverage some unconventional CSS matrices to build a custom scroller that doesn’t require any JavaScript while scrolling, just some setup code.

I’ll embed a copy here:

A Cross-Browser Demo of Custom Scrollbars

It’s fairly consistent across Chrome, Safari, and Firefox:

Here’s a screenshot of that in case you’re looking on mobile or something and can’t see these:

An example of Styling Scrollbars in CSS. It's a thin scrollbar with the background in a light blue and the rounded thumb in a dark blue.

Note about Firefox on macOS

The scrollbar-width property will work no matter what, but the scrollbar-color property only works if you have “Show scroll bars: Always” checked in General System Preferences.