'How to show scrollbar on hover with fade effect

Following this great article (https://css-tricks.com/scrollbars-on-hover/), I tried to create an scrollbar that is only shown on hover, with a fade-in/out effect.

mask-image cuts 17px from the right side of .a and .b so I can animate the effect by changing the mask-position. This is okay for .b, because there's nothing in the right side of the screen to worry about. However, there are 3 problems with the sidebar:

  1. The mask is shown/hidden even when there's no overflow and thus no scrollbar - See sample 2

  2. The cut part destroys the balance of sidebar width (The right side will have less padding than the left)

  3. The scrollbar appears to be outside the sidebar, not inside.

I want to have a colored mask rgba(0,0,0,0.4), instead of a transparent one.

Demo:

(Open in fullscreen for better visibility)

.grid {
  display: grid;
  display: grid;
  grid-template-columns: minmax(260px, auto) 1fr;
  background: linear-gradient(to right, brown, orange);
  gap: 16px;
}

.a,
.b {
  color: white;
  height: 300px;
  overflow-y: auto;
  mask-image: linear-gradient(to top, transparent, black), linear-gradient(to left, transparent 17px, black 17px);
  mask-size: 100% 40000px;
  mask-position: left bottom;
  transition: mask-position 0.3s;
}

.a:hover,
.b:hover {
  mask-position: left top;
}

.a {
  background: rgba(0, 0, 0, 0.4);
}
<h1>Sample 1</h1>

<div class="grid">
  <div class="a">
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
  </div>
  <div class="b">
   <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>    <p>ksjdfh</p>
  </div>
</div>

<h1>Sample 2</h1>

<div class="grid">
  <div class="a">
    <p>ksjdfh</p>
    <p>ksjdfh</p>
    <p>ksjdfh</p>
  </div>
  <div class="b">
    <p>ksjdfh</p>
    <p>ksjdfh</p>
  
  </div>
</div>

What I tried

I tried to use pseudo-elements to create a 17px-wide bar and fill the right side of sidebar when the mask is applied:

.b:before{
    content: "";
    width: 17px;
    background-color: rgba(0,0,0, 0.4);
    height: 100vh;
    position: absolute;
    left: -17px;
    top: 0;
}

/* also tried the similar thing for a:after */

But this bar gets masked too. I also tried z-index, but no luck!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source