Busti Busti - 4 months ago 55
CSS Question

use transition on ::-webkit-scrollbar?

is it possible to use transitions on webkit scrollbars?
I tried:

div#main::-webkit-scrollbar-thumb {
background: rgba(255,204,102,0.25);
-webkit-transition: background 1s;
transition: background 1s;
}

div#main:hover::-webkit-scrollbar-thumb {
background: rgba(255,204,102,1);
}


but it isn't working.
Or is it possible to create a similar effect (without javascript)?

Here is a jsfiddle showing the rgba transition problem

Answer

Short answer: No, it's not possible to use transition on a ::-webkit-scrollbar

Long answer: There are means to achieve a similar effect entirely in CSS.

Explanation:

  1. We need to create an outer container that will scroll. Then we want to create an inner container.
  2. The outer container will have a background-color property. This property will match the color we want to transition on for the scrollbar.
  3. The inner container will match the height of the outer container and will have a background-color that masks the outer container.
  4. The scrollbar's background-color will inherit the outer container's.
  5. The transition property will be applied to the background-color of the outer container.

A major disadvantage here is that you have to do some masking. This can be a bit of a hassle if your background isn't a solid color, since the inner container will most likely need to match. If that's not a worry, this will work for you. Here's the code to put it all together for a page with a horizontally scrolling component.

HTML

<div id="container-outer">
    <div id="container-inner">
        <!-- Content goes here -->
    </div>
</div>

CSS

    /* Scrollbar */
    ::-webkit-scrollbar {
        border: 0;
        height: 10px;
    }
    ::-webkit-scrollbar-track {
        background: rgba(0,0,0,0);
    }
    ::-webkit-scrollbar-thumb {
        background-color: inherit; /* Inherits from outer container */
        border-radius: 20px;
    }

    /* Container */
    #container-outer {
        overflow-y: hidden;
        overflow-x: scroll; /* Horizontal-only scrolling */
        height: 400px;
        background-color: white; /* Initial color of the scrollbar */
        transition: background-color 200ms;
    }
    #container-outer:hover {
        background-color: red; /* Hover state color of the scrollbar */
    }
    #container-inner {
        background-color: white; /* Masks outer container */
        font-size: 0;
        height: inherit; /* Inherits from outer container */
        width: 10000px; /* Set to see the scrolling effect */
    }

Notes:

  • It should be obvious, but this is a Webkit solution. The question was specifically about Webkit and not anything else, so this answer is only in regards to Webkit.
  • Your outer container will probably need a max-width that will match whatever your inner container's width is, otherwise you may see some oddity on extremely large displays. This is an edge case for when the browser width is larger than the horizontally scrolling content width. This is assuming you are using a horizontal scroll, as the example code does.
  • Hovering styles don't work as intended on mobile in most circumstances. This is an issue given how there is a huge market penetration of Webkit mobile browsers. Take that into consideration before using this solution.