Search code examples
htmlcssscrollbarchromiumweb-component

Stop a -webkit-scrollbar-track appearing on top of other content when overflow: overlay


I have a set of styles that create a slim overlay scrollbar for Chromium/Webkit using -webkit-scrollbar-track (fallbacks in FX don't have this issue), something like:

#wrapper {
  height: 125px;
  display: flex;
}

.slim-scroll {
    flex: 1;
    overflow-y: overlay !important;
    padding-right: calc(8px * 1.5);
}

    .slim-scroll::-webkit-scrollbar-track
    {
    }
        .slim-scroll:hover::-webkit-scrollbar-track { 
            -webkit-box-shadow: inset 0 0 8px rgba(0,0,0,0.3);
            box-shadow: inset 0 0 8px rgba(0,0,0,0.3);
            background: grey; 
        }

    .slim-scroll::-webkit-scrollbar
    {   
        height: 8px;
        width: 8px;
        background: none;
        -webkit-box-shadow: inset 0 0 8px rgba(0,0,0,0.1);
        box-shadow: inset 0 0 8px rgba(0,0,0,0.1);
    }

    .slim-scroll::-webkit-scrollbar-thumb
    {
        background: black;
    }
        .slim-scroll:hover::-webkit-scrollbar-thumb { background: red; }
<div id="wrapper">
  <div class="slim-scroll">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam tincidunt risus eros, non fermentum quam lacinia eu. In nec nibh ipsum. Nunc sollicitudin lectus sed leo euismod, sed tincidunt nunc eleifend. Nunc sed nunc felis. Nunc dolor metus, luctus in aliquet sit amet, congue sed lacus. Cras pellentesque nisl quis quam vehicula, eget fermentum metus luctus. Vestibulum eget arcu eget nisl volutpat tincidunt. Maecenas pharetra ex ex, sit amet eleifend leo hendrerit ac.

Nulla sed tristique quam. Aliquam quis nisi sit amet mi hendrerit eleifend a feugiat neque. Suspendisse tincidunt auctor dui, quis convallis eros bibendum in. Donec dui ex, sollicitudin quis tristique a, interdum nec nibh. Duis mattis, leo eget consectetur mollis, enim tellus imperdiet ante, eu viverra felis ante scelerisque velit. Integer sit amet tincidunt lectus. Nulla hendrerit lectus est, a mattis augue cursus et. Praesent sit amet nunc lorem. Etiam sollicitudin ut neque a ultrices. Phasellus vel nulla mauris. Donec malesuada porta dui. Praesent mi augue, laoreet nec consectetur nec, tincidunt in erat. Aliquam laoreet vel dolor et mattis. Fusce eu augue ut felis posuere auctor.
  </div>
</div>

However, in the wild this has a weird bug: sometimes, not always, the -webkit-scrollbar-track appears on top of other content.

In this screen shot there are two web components, both with shadow DOM and using the style for the scrollbar, but the one on the left appears correctly, while on the right the -webkit-scrollbar-track and -webkit-scrollbar-thumb are on top of the next panel:

image showing scroll appearing over subsequent content

I can't reproduce this bug in a simple example - I don't know what's different between the two web components (or rather there are a huge number of differences, but I don't know which one is causing this).

Update

Thanks @jolan for the idea that has helped me find the cause: switching from overflow-y: overlay to overflow-y: auto stops the scroll bar appearing on top of other content.

That only gets me part way there - this uses overlay specifically (rather than scroll or auto because I want to keep the horizontal layout of the content the same regardless of parent height, but I also don't want to show a scrollbar when the content isn't scrollable.

  • Is this a known bug with overlay? Can anyone point me to a blink/webkit issue?

  • Does anyone know why overlay does this and is there any way to resolve it without switching to auto or scroll?

  • Is there a CSS solution that doesn't change the content width depending on vertical height? It would have to work in flex and grid contexts as well as explicit height/width.


Solution

  • First, can you try to do this without flexbox? Flex still has some issues, especially on special cases like this.

    Second I put all css on one div. As that is the div you want the scrollbar on.

    Update: This fixes the original problem

    Third: replace overflow-y: overlay with overflow-y: auto

    Update: second question

    overlay is deprecated

    • According to https://developer.mozilla.org/en-US/docs/Web/CSS/overflow this is a depreacted issue. According to https://bugs.webkit.org/show_bug.cgi?id=189811 it was an 'expected failure'.

    • As 'overflow-y: overlay' is deprecated (for at least 7 years if i read it correctly) it hasn't been maintained at all. This means that when -webkit-browsers update, they will not be taking this feature into account. Bugs like this will slowly show op as the browsers are evolving.

    • I would suggest one of next solutions:

      1. There are ways to completely hide the scrollbar (crossbrowser compatible): https://www.w3schools.com/howto/howto_css_hide_scrollbars.asp
      2. I suppose it's possible to style the scrollbar absolutely, but styling scrollbars is !not a crossbrowser solution!
      3. My suggestion: Styling or hiding scrollbars is generally not a good idea. There are very good reasons the 'overflow-y: overlay' feature is deprecated. I would suggest finding a different approach.

    Last note: I would like to point out that overflow-y: overlay is a webkit feature. It will also not work cross-browser.