Customizing Scrollbar Using CSS
Written by Frank Fiegel on .
A user reported a bug and attached a screenshot that looks like this:
The bug is not related to the scrollbar, but I wasn't aware that that's how Glama looks on Windows.
I wanted to customize the scrollbar to look like macOS, so I started to tinker with the CSS. To my surprise, this took quite a few iteration to get the desired result. This post summarizes the solution.
CSS
Here is the CSS that I used to make scrollbars on Windows look like macOS:
The body.platform-windows
selector applies the styles to the body element when the platform-windows
class is present. There is no need for us to override the default macOS scrollbar styles, so we add a platform-*
class to the body
element and use it to conditionally apply the styles.
The result is identical to the macOS scrollbar. However, there is one small difference: macOS srollbar fades out when not in use, while Windows scrollbar stays visible. I wanted to replicate this on Windows.
Easing the Scrollbar Transition
If you are familiar with the scrollbar in macOS, it only shows when you are actively scrolling. After the user stops scrolling, the scrollbar fades out. This is how it looks on macOS:
Let's see how we can achieve the same effect on Windows.
Determining When the Scrollbar Is Active
The first task is to determine when an element is being scrolled. We need this so that we could transition between showing and hiding the scrollbar.
To do this, we use a React hook called useScrollbarThumb
that returns a scrolling
boolean and a setScrolling
function. The scrolling
boolean is true when the scrollbar is active, and the setScrolling
function is used to set the scrolling
boolean to true or false.
Every element that needs to use the macOS-style scrollbar will need to need to have the data-scrollbar-thumb
attribute. Here is how:
Now that we have data-scrollbar-thumb
that is going to be either true
or false
, we can use it to conditionally apply the scrollbar styles.
My first attempt was to just add transition: background-color 1s
to the ::-webkit-scrollbar-thumb
selector, but this didn't work. Turns out, we need a more clever solution.
Using CSS Variables
I was able to get the desired effect by using CSS variables. Here is the final CSS:
Here is brief explanation of the key parts:
- We are defining a CSS variable called
--scrollbar-thumb-color
that will be used to set the background color of the scrollbar thumb. - We are using
[data-scrollbar-thumb="true"]
to determine if the element is being scrolled. - We are using
transition
to smoothly transition the background color of the scrollbar thumb.
Here is the final result:
I am using BrowserStack to validate the results on Windows, and as far as I can tell, it looks like the scrollbar is working as expected.
Browser Support
It is worth mentioning that not all browsers support -webkit-scrollbar
properties (namely, Firefox).
Depeding on which browsers you are targeting, you may need to add a fallback, e.g.,
Conclusion
That's it! This is how I customized Glama's scrollbars to provide a consistent experience across Windows and macOS.
Whether customizing the default system scrollbar is the right choice depends on your specific needs. While consistency across platforms can enhance your application's visual identity, it's worth considering that users are familiar with their system's default scrollbar behavior. In our case, we prioritized visual consistency, but your mileage may vary depending on your project's requirements.