First, scrollbars are a usability and accessibility thing. Second, a rule of thumb: if an area scrolls, it should have a visible scrollbar. But the web is a big place and I like tricks, so I’m going to cover the idea of only revealing them on hover. Even macOS itself¹ hides scrollbars by default, revealing them contextually and on interaction. Same on iOS, leading to confusing moments.
All that aside, here’s a way to hide scrollbars by default, only revealing them when the element is hovered. It was created by Thomas Gladdines, who also emailed me about it:
In quick testing on my machine, it works across Chrome, Firefox, and Safari, regardless of my macOS settings. So pretty robust.
The trick is that mask
covers the scrollbar! So, if you create a mask
that is exactly as wide as the scrollbar (here, I’m just guessing that 17px will cover it) and super duper tall (both of which should probably be calculated by a script), it can perfectly cover the scrollbar. You can even transition
the position of the mask, faking a fading in/out effect. Very clever.
Notably, this is the real scrollbar of the element, and not a faked one. Faking one could be another approach. Ben Nadel covered how Slack does that. Their trick is to force the scrollbar to render in an area hidden by overflow, and make a virtual scrollbar that mimics the native one (which you’d then have more direct control over). It’s not forcing the scrollbar either, which is something else you can do if so motivated. And nothing about this prevents you from styling the scrollbar, which might actually have some benefits like specifying the exact width of it.
- As I write:
If your device allows gestures, scroll bars are hidden until you start scrolling. Otherwise, they’re visible.
↩️
I always use the
::-webkit-scrollbar-*
pseudo-properties, they are supported widely except Firefox and IE, the only drawback is that transitions are not supported by those properties.While Firefox supports the standard
scrollbar-*
properties. They are not as powerful as::-webkit-scrollbar-*
, but they support transition onscrollbar-color
https://codepen.io/CarterLi/pen/yLarOvN
The main idea behind this trick was to resolve the long standing issue of fading in/out a native (styled) scrollbar on webkit browsers. The webkit psuedo selectors sadly don’t support transitions.
The good thing about MacOS is that it gives you the choice. If you need the scrollbars for accessibility you get to have them.
We only need these hacks because Windows refuses to implement good scrollbars at an OS level.
OSX Lion is about to turn 10 years old…
Maybe the next Windows will have it.
If you must hide the scrollbars (and just, why, but) make sure to only do so on devices where the use can actually hover. Which, if we’re being reasonable, is probably the least of your site’s traffic, but, hey.
You covered it here:
At 2014 (for me like yesterday) I wrote a super tiny piece of javascript which applies fake scrollbars (on a container with overflowing content), because of the possibilities of styling which are unparalleled to anything native customization allowed at the time, and still allows at this present (and probably the future too)
https://github.com/yaireo/fakescroll
Would it be possible to use
blend-mode
to so the text is invisible while still concealing the scrollbar?A longshot but… might work depending on browser vendor.
How would you go about using this method on both vertical and horizontal scrollbars simultaneously
It’s also possible to use scrollbar-color and ::-webkit-scrollbar-thumb / ::-webkit-scrollbar. Make them transparent and on :hover change color.