Ultimate Guide to Create Custom Scrollbars in CSS

Robin
Updated on March 18, 2023

Sometimes we want to create custom scrollbars in CSS for our website to make it stand out from the competition. But it seems a little complicated to style a scrollbar. Because we have to face some issues in the process while creating custom scrollbars.

In this article, I will show you how you can create custom scrollbars for your website using pure CSS. I will discuss all the complications that you might face and how you can solve them.

There are a few major problems that you will face while styling your website scrollbar.

  • We can not select scrollbars easily.
  • There are different types of scrollbars.
  • All Browsers don't support the same CSS selectors.
  • Different browsers show scrollbars in different styles.
  • Sometimes scrollbars show up in unexpected positions.
  • It might hamper user experience if we don't follow some good practices.

There are many more problems we will discuss in this article. Because of these obstacles we often don't want to style our scrollbars.

Also Read: How to Style HTML <textarea> with CSS (Quick Hacks)

The browser's default scrollbars are just fine. It is not compulsory that we have to create a custom design scrollbar. All I want to say is that if you want, you can do this.

How do you create custom scrollbars in CSS?

First, we need to know the different parts of a scrollbar. Because we have to style different parts separately.

We will add two sets to style for supporting multiple browsers. Because styling scrollbars in Firefox is different than in other browsers.

We can also show our scrollbar when we need them. Otherwise, we can hide it to provide more space for our website users.

Finally, we also need to follow some good techniques so that our scrollbar increases the user experience.

Types of Scrollbars (Vertical/Horizontal)

There are two types of scrollbars we see on a web page.

  • Vertical Scrollbar.
  • Horizontial scrollbar.

Normally, horizontal scrollbars are used in a specific section. For example, if you want to show a list of posts, you might want to display them horizontally. Because if you display a large number of blog posts vertically it might take up huge space and users have to scroll for a long time.

To solve this problem, you can show those posts horizontally and the browser will add a horizontal scrollbar when your content crosses the available space on the user's device.

And we all know about vertical scrollbars. It appears on the right side of almost every web page.

We can also use vertical scrollbars in a specific section. For example, if you set a fixed height for a section on your page and add overflow: auto; then browsers will show a vertical scrollbar if the content inside that section is more than the fixed height.

Scrollbar Components

When we see a scrollbar on a web page, we see a few parts. There are two arrow buttons up and down for the vertical scrollbar. There are also two arrow buttons left and right for the horizontal scrollbar.

Showing all the components of a web page scrollbar

Other than these buttons, there are two other components. One is thumb another is the thack.

  • Scrollbar Track.
  • Scrollbar Thumb.
  • Arrow Buttons (Up and down/Left and right).

The thumb is the portion that we can move and show us the position where we are on a page.

On the other hand, the track is the portion behind the thumb that works as background for the thumb. We move the thumb inside the track.

We will customize all of these components in this article.

Create Custom Scrollbars in Chrome, Edge, and Safari

As I said before, you have to add two sets of styles for supporting all browsers. First, I will show you how you can customize your scrollbar in browsers other than Firefox.

In the next section, you will see the styles that work only in Firefox.

customize scrollbars in Google Chrome browser without showing the arrow buttons

You can style your horizontal and vertical scrollbars together. The same styles will be applied to both.

But if you need different styles for horizontal and vertical you can do that too.

To style, both scrollbars together add the following code to your stylesheet.

          ::-webkit-scrollbar {
    width: 1.4vw;
    height: 3.3vh;
}

::-webkit-scrollbar-track {
    background-color: #f5f5f5;
    border-radius: 10px;
    margin-top: 3px;
    margin-bottom: 3px;
    box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}

::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background-color: #f90;
    background-image: -webkit-linear-gradient(
        45deg,
        rgba(255, 255, 255, 0.2) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.2) 50%,
        rgba(255, 255, 255, 0.2) 75%,
        transparent 75%,
        transparent
    );
}

::-webkit-scrollbar-thumb:hover {
    background-color: #ec8f02;
}
        

Here, I have used 3 pseudo-elements to add style to the scrollbar.

  • ::-webkit-scrollbar - It affects the entire scrollbar.
  • ::-webkit-scrollbar-thumb - It affects the draggable scrolling handle that we can move.
  • ::-webkit-scrollbar-track - It affects the space where we move the scrolling handle.

You might think if ::-webkit-scrollbar works for the entire scrollbar then why you will use the other two. The problem is that all CSS properties don't work inside ::-webkit-scrollbar element.

For example, I have used border-radius property in ::-webkit-scrollbar-track because border-radius property does not work inside ::-webkit-scrollbar element.

Here, margin-top and margin-bottom properties inside ::-webkit-scrollbar-track will only work for vertical scrollbars and if you add margin-left and margin-right, these properties will only work for horizontal scrollbars.

I have set width and height properties inside ::-webkit-scrollbar because I need this for the entire scrollbar.

Why do you use width and height at the same time?

the width property only works for vertical scrollbars and height property only works for horizontal scrollbars.

When you set width it will increase the size of the vertical scrollbars and height will increase the size of the horizontal scrollbars.

I have used viewport width (vw) and viewport height (vh) CSS units for width and height properties respectively. Because if you use pixel (px) unit here then the scrollbar size will increase and decrease when you zoom in or out your web page.

I don't want that. I want a fixed-size scrollbar on my page so that it does not change its size when users zoom in or out of my web page.

Style Horizontal Scrollbars

The above code adds style to both types of scrollbars. If you want to customize only your horizontal scrollbars then this is the solution for you.

Usually, a horizontal scrollbar is added to a specific section. You can use the CSS class or id of that section with those pseudo-elements to apply style only for that section.

For example, if your section that is showing a horizontal scrollbar has .products class, then you can select that section this way:

  • .products::-webkit-scrollbar
  • .products::-webkit-scrollbar-track
  • .products::-webkit-scrollbar-thumb

Everything else is the same. You can use CSS properties in the same way mentioned earlier.

The difference is that this time style will only apply to the scrollbar in .products class section.

Style Vertical Scrollbars

Similarly, if you want to customize the main vertical scrollbar on your web page, you can use body or html tags with those pseudo-elements.

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

OR

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

Both work in a similar way. When you use this way, styles will be applied only to the main vertical scrollbar, not to the other scrollbars on the web page.

Also Read: How to Get Scrollable Height of a Page or Element in JavaScript

How to Customize Arrow Buttons in Scrollbars

When you add the above code to your stylesheet you will notice there are no arrow buttons. If you don't want to use those buttons then the first example will be fine for you.

But if you want to include arrow buttons with your custom scrollbars then you can use the code mentioned below.

          ::-webkit-scrollbar {
    width: 1.4vw;
    height: 3.3vh;
}

::-webkit-scrollbar-track {
    background-color: #f5f5f5;
    box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}

::-webkit-scrollbar-thumb {
    background-color: #f90;
    background-image: -webkit-linear-gradient(
        45deg,
        rgba(255, 255, 255, 0.2) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.2) 50%,
        rgba(255, 255, 255, 0.2) 75%,
        transparent 75%,
        transparent
    );
}

::-webkit-scrollbar-thumb:hover {
    background-color: #ec8f02;
}
        

In this example, I have changed some styles from the first one. This piece of code will customize the main scrollbar. This is the base style for our scrollbar.

          /* Buttons */
::-webkit-scrollbar-button:single-button {
    background-color: #ece4e4;
    display: block;
    background-size: 10px;
    background-repeat: no-repeat;
}

::-webkit-scrollbar-button:single-button:hover {
    background-color: #d0cbcb;
}
        

The above code will set the base style for our buttons. Here you can add general styles like background.

To add style to arrow buttons we have to use ::-webkit-scrollbar-button pseudo-element along with other pseudo-classes.

  • :single-button
  • :horizontal
  • :vertical
  • :decrement
  • :increment

Now I will customize the arrow buttons.

customize scrollbars in Google Chrome browser with the arrow buttons

Style Arrow Buttons in Horizontal Scrollbars

To style arrow buttons in horizontal scrollbars, you have to use :horizontal pseudo-class.

Now to add style to the left side arrow button of a horizontal scrollbar you need to use :decrement with :horizontal pseudo-class.

Then for the right side arrow button, you can use :increment with :horizontal pseudo-class.

Here for each button, I am setting the width, height, background-position, and background-image CSS properties.

I have added SVG icons as the background image.

          /* Left */
::-webkit-scrollbar-button:single-button:horizontal:decrement {
    height: 12px;
    width: 15px;
    background-position: 4px 5px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='rgb(112, 112, 112)'><polygon points='0,50 50,100 50,0'/></svg>");
}

::-webkit-scrollbar-button:single-button:horizontal:decrement:active {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='rgb(128, 128, 128)'><polygon points='0,50 50,100 50,0'/></svg>");
}

/* Right */
::-webkit-scrollbar-button:single-button:horizontal:increment {
    height: 12px;
    width: 15px;
    background-position: 5px 5px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='rgb(96, 96, 96)'><polygon points='0,0 0,100 50,50'/></svg>");
}

::-webkit-scrollbar-button:single-button:horizontal:increment:active {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='rgb(128, 128, 128)'><polygon points='0,0 0,100 50,50'/></svg>");
}
        

Style Arrow Buttons in Vertical Scrollbars

For vertical scrollbar arrow buttons, you have to use :vertical pseudo-class to add custom styles.

Two other pseudo-classes are used :decrement and :increment with :vertical for up and down arrow buttons respectively.

In this case, you can also add SVG icons and other CSS properties.

          /* Up */
::-webkit-scrollbar-button:single-button:vertical:decrement {
    height: 14px;
    width: 16px;
    background-position: center 4px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='rgb(96, 96, 96)'><polygon points='50,00 0,50 100,50'/></svg>");
}

::-webkit-scrollbar-button:single-button:vertical:decrement:active {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='rgb(128, 128, 128)'><polygon points='50,00 0,50 100,50'/></svg>");
} 

/* Down */
::-webkit-scrollbar-button:single-button:vertical:increment {
    height: 14px;
    width: 16px;
    background-position: center 5px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='rgb(96, 96, 96)'><polygon points='0,0 100,0 50,50'/></svg>");
}

::-webkit-scrollbar-button:single-button:vertical:increment:active {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='rgb(128, 128, 128)'><polygon points='0,0 100,0 50,50'/></svg>");
}
        

Create Custom Scrollbars in Firefox

For customization in Firefox, we have limited options. Firefox supports two CSS properties to add custom style to its scrollbars.

  • scrollbar-width - This property allows us to set the width or thickness of the scrollbar. It accepts three values: auto, thin, and none. Here, auto is the default value, thin makes the scrollbar thinner than the default and none removes the scrollbar from the web page.
  • scrollbar-color - This property allows us to set the color for the thumb and track of the scrollbar. It accepts auto as its value. auto is the default value. But you can pass two valid color names like red, blue, etc or you can pass two color codes like #FC9901, #F5F5F5.

In scrollbar-color property, first color name, or color code applies to the thumb of the scrollbar that we can move. The second color name or color code applies to the track of the scrollbar where we move the thumb.

Note: Whenever we use these two properties, we must use them on the root element.

Showing web page scrollbar in Firefox browser when scrollbar-width is set to thin

You already know that we can add styles for our scrollbars in two ways. First, in the global scope that will apply to all scrollbars on the page. Second, we add style to a specific section on the page.

In order to add this to the global scope, you can follow the code below.

          * {
    scrollbar-width: thin;
    scrollbar-color: #f90 #f5f5f5;;
}
        

Here, I am selecting * it means everything. When you apply these properties using * then it works properly for all scrollbars.

I have tried to use html or body instead but they don't work properly. When I have used html then scrollbar-color works for all scrollbars but scrollbar-width works only in the vertical scrollbar.

          html {
    scrollbar-width: thin;
    scrollbar-color: #f90 #f5f5f5;
}
        

When I have used body the vertical scrollbar has no effect and in the horizontal scrollbar, only scrollbar-color works but scrollbar-width property does not work. So it is best to use these properties with * selector for the global scope.

          body {
    scrollbar-width: thin;
    scrollbar-color: #f90 #f5f5f5;
}
        

In order to use them for a specific section, you have to put them in the root element of that section.

What do I mean by the root element?

If you have a section where you display a list of products and in this section, you want to apply style for the scrollbar. For this section, the element in which all the products are present, you must apply these properties to that element.

          <div class="products">
    <div class="single-product">
        <div class="accomodation_item text-center">
            <div class="hotel_img">
                <img src="image/room1.jpg" alt="">
                <a href="#" class="btn theme_btn button_hover">Book Now</a>
            </div>
            <a href="#">
                <h4 class="sec_h4">Double Deluxe Room</h4>
            </a>
        </div>
    </div>
    <div class="single-product">
        <div class="accomodation_item text-center">
            <div class="hotel_img">
                <img src="image/room1.jpg" alt="">
                <a href="#" class="btn theme_btn button_hover">Book Now</a>
            </div>
            <a href="#">
                <h4 class="sec_h4">Double Deluxe Room</h4>
            </a>
        </div>
    </div>
</div>
        

In the above example, you can see all the products are inside a div that has a class of .products so we have to add those CSS properties in this class to add style to the scrollbar.

          .products {    
    width: 300px;
    height: 100px;
    overflow-y: auto;
    scrollbar-width: auto;
    scrollbar-color: #f90 #f5f5f5;
}
        

When you set thin for scrollbar-width property, it removes the arrow buttons and the scrollbar becomes very thin. It becomes very difficult to use.

But if you just use scrollbar-color property without scrollbar-width then it gets the default thickness along with the color. I think it looks better and provides a better user experience.

Showing web page scrollbar in Firefox browser when scrollbar-width is set to auto

By the way, if you have to use the scrollbar-width property for any reason, then set it to auto not thin. When you set its value auto, it output the same result.

How to Add Hover Effect in Custom Scrollbars

You can add the hover effect to your scrollbar thumb using :hover CSS pseudo-class.

          /* Works on Chrome, Edge, and Safari */
::-webkit-scrollbar-thumb:hover {
    background-color: #ec8f02;
}

/* Works on Firefox */
.products {    
    width: 300px;
    height: 100px;
    overflow-y: auto;
    scrollbar-width: auto;
    scrollbar-color: #f90 #f5f5f5;
    transition: scrollbar-color 0.3s ease-out;
}

.products:hover {
    scrollbar-color: #ec8f02 #f5f5f5;
}
        

For Chrome and other browsers, apply :hover to the ::-webkit-scrollbar-thumb pseudo-element. You can also use it for a specific section.

For Firefox, you can add the hover effect to a section scrollbar. In this case, you also can apply transition property for your hover but for ::-webkit-scrollbar-thumb it is not possible.

Show Scrollbars When They Are Needed

You can make a section scrollable by adding an overflow property. This property accepts 4 values. These are: visible, scroll, auto, and hidden. Here visible is the default value.

  • visible - It means the content in the section will show outside if there is not enough space but there will be no scrollbar.
  • scroll - It means there will a scrollbar to see the rest of the content. But in this case, if the content is less user does not need a scrollbar still scrollbar will stay.
  • auto - It means a user will see a scrollbar if the content needs more space than the original section but if the content is less then the scrollbar will not show up.
  • hidden - It means there will be no scrollbar. If the section has more content, the user can not see the rest of the content.

So, you can see that if you use the value auto, the scrollbar in a section will show up conditionally. If that section has more content and needs more space, the scrollbar will show up. Otherwise, users will not get any scrollbar.

          .products {
    overflow-y: auto;
}
        

Good Practices While Creating Custom Scrollbars

After we know how you can create custom scrollbars for your web page, you should follow some techniques. Because if you don't follow those good practices, it might damage the user experience.

  • Scrollbar width should not be too thin or too thick.
  • Add a scrollbar to a section if it is absolutely necessary. Otherwise, try to avoid it.
  • If you have to add a scrollbar, always show important information above the fold.
  • There should be proper contrast between the colors of the scrollbar thumb and track.
  • Hide and show scrollbar automatically. If the content is less then hide the scrollbar. Otherwise shows it.

Scrollbar Browser Support

Let's check the browser support for the properties that we have seen so far. All the -webkit- versions are supported in most browsers like Chrome, Safari, Edge, Opera, Android, etc.

Browser support of webkit-scrollbar and scrollbar-width CSS properties

You can check by yourself by clicking the links below.

For Firefox, there are two CSS properties. If you check their support, you will find they are supported only in Firefox browsers.

You can check their browser support here.

Scrollbar Selectors

For WebKit browsers, you can use the following pseudo-elements to customize various parts of the scrollbar.

  • ::-webkit-scrollbar is used to add style to the entire scrollbar, like background.
  • ::-webkit-scrollbar-button is used to customize the arrow buttons in the scrollbars.
  • ::-webkit-scrollbar-thumb is used to add style to the draggable element in the scrollbar that moves when someone scrolls the page.
  • ::-webkit-scrollbar-track is the progress bar where the thumb moves up and down or left and right.
  • ::-webkit-scrollbar-track-piece is part of the track that is not covered by the draggable element (thumb).
  • ::-webkit-scrollbar-corner is the corner part where both horizontal and vertical scrollbars meet. This is normally the bottom-right corner of a browser window.
  • ::-webkit-resizer is the draggable resizing handle that appears above the scrollbar corner at the bottom corner of some elements

For the Firefox browser, you can use these two CSS properties to customize the scrollbars.

  • scrollbar-color is used to add color to the thumb and track of the scrollbar.
  • scrollbar-width is used to add width to the scrollbar with auto, none and thin values.

Conclusion

In this article, I have discussed all the elements that a scrollbar has, how you can customize them, their browser support, etc.

You also know what are the best practices you need to follow while customizing scrollbars on your web page. You can do all of these just using CSS.

I hope that now you have a clear idea of how to create custom scrollbars in CSS for any web page.

Related Posts