DEV Community

loading...
Cover image for How to make scrollbar with changing gradient on scroll using 10 lines of CSS 🚀

How to make scrollbar with changing gradient on scroll using 10 lines of CSS 🚀

thesoreon profile image Paul Susicky ・3 min read

Introduction

You may know we can use a set of CSS pseudo-elements to customize scrollbar on our website, but did you know we can use a special trick to make a gradient scrollbar that changes on scroll only with CSS?

Our final result should look like codepen below. The CSS behind it isn't complicated and it consists only of 10 (+ 2 empty) lines of code. If you want to discover the magic on your own, see the codepen. Otherwise, keep reading to see what trick did we do to make this work. 😎

Note: if you see the default scrollbar make sure, you are using a browser which supports scrollbar pseudo-elements (any Webkit based browser is fine)

We will make use of these pseudo-elements:

  • ::-webkit-scrollbar
  • ::-webkit-scrollbar-track
  • ::-webkit-scrollbar-thumb

However, there are a few more available if you want to see a full list of scrollbar's pseudo-elements visit MDN.

The code

Let's start with the first pseudo-element ::-webkit-scrollbar to set a width of our scroll. So in CSS, it looks like this:

::-webkit-scrollbar {
  width: 20px;
}

Next, we're gonna add our desired gradient (you can create one with this handy tool https://cssgradient.io/.

Do you have your gradient ready? So add it to ::-webkit-scrollbar-track pseudo-element as background property. This will make our scrollbar to be covered by the gradient.

::-webkit-scrollbar-track {
  background:  linear-gradient(0deg, rgba(255, 0, 0, 1) 0%, rgba(7, 0, 211, 1) 100%);
}

The trick

Now the most important step, we're gonna customize the scroll handle (called thumb pseudo-element). Firstly, try to add a solid background colour to the thumb.

::-webkit-scrollbar-thumb {
  background: lime;
}

You will see the typical scrollbar handle with green colour. Perfect. Now let's make it transparent. So use background: transparent; or opacity: 0;.

We are not able to see it now, but we know that it is there and we can see the gradient through it, nice! So all we need to do is to render all external space with solid colour. How do we do that?

With the use of a box-shadow property! Let's refresh what does box-shadow property consists of:

.box {
  box-shadow: 0px 0px 4px ??? black;
}
  • 0px: horitontal (x-axis) offset
  • 0px: vertical (y-axis) offset
  • 4px: blur
  • ???: the secret property we will make use of
  • black: color of the box-shadow

The fourth hidden property is called spread and it increases/decreases the size of the box-shadow and that's perfect! If we set it to an enormous value with zero blur, it will cover all space around the scrollbar handle. That's exactly what we want! Let's try it in the code!

Make sure you gave it a big value, so it covers the whole scrollbar.

::-webkit-scrollbar-thumb {
  background: transparent;
  box-shadow: 0px 0px 0px 100000vh black;
}

And we are finished, and we can see how our scrollbar gradient is changing on scroll. The whole principle works on the idea of seeing through the handle the gradient background of the scrollbar. And cover all outside space with a solid colour, so cool 😎

Composed together the code looks like this:

::-webkit-scrollbar {
  width: 20px;
}

::-webkit-scrollbar-track {
  background:  linear-gradient(0deg, rgba(255, 0, 0, 1) 0%, rgba(7, 0, 211, 1) 100%);
}

::-webkit-scrollbar-thumb {
  background: transparent;
  box-shadow: 0px 0px 0px 100000vh black;
}

BIG Credits 👏

I didn't come up with this neat trick using box-shadow, all the credits should go to James Warner, who is an amazing web developer streaming on Twitch.

jmswrnr image

Surely go check him out! He is currently developing an astonishing personal website using WebGL, React, Next.js and Sanity.io! Just see a snippet of his progress below:

Alt Text

The screenshot itself looks cool, but see it in action here

Discussion (0)

pic
Editor guide