[css] Make scrollbars only visible when a Div is hovered over?

I am trying to figure out how to have a scrollable div that only shows its scrollbars when Hovered.

Example is Google Image search, in the image below you can see how the left sidebar does not appear to be scroll-able until you hover the mouse over it.

Is this possible with CSS or is Javascript required? If possible maybe a quick example how to do such a task?

Example

This question is related to css

The answer is


Answer by @Calvin Froedge is the shortest answer but have an issue also mentioned by @kizu. Due to inconsistent width of the div the div will flick on hover. To solve this issue add minus margin to the right on hover

#div { 
     overflow:hidden;
     height:whatever px; 
}
#div:hover { 
     overflow-y:scroll; 
     margin-right: -15px; // adjust according to scrollbar width  
}

Give the div a fixed height and srcoll:hidden; and on hover change the scroll to auto;

#test_scroll{ height:300px; overflow:hidden;}
#test_scroll:hover{overflow-y:auto;}

Here is an example. http://jsfiddle.net/Lywpk/


If you are only concern about showing/hiding, this code would work just fine:

$("#leftDiv").hover(function(){$(this).css("overflow","scroll");},function(){$(this).css("overflow","hidden");});

However, it might modify some elements in your design, in case you are using width=100%, considering that when you hide the scrollbar, it creates a little bit of more room for your width.


One trick for this, for webkit browsers, is to create an invisible scrollbar, and then make it appear on hover. This method does not affect the scrolling area width as the space needed for the scrollbar is already there.

Something like this:

_x000D_
_x000D_
body {_x000D_
  height: 500px;_x000D_
  &::-webkit-scrollbar {_x000D_
    background-color: transparent;_x000D_
    width: 10px;_x000D_
  }_x000D_
  &::-webkit-scrollbar-thumb {_x000D_
    background-color: transparent;_x000D_
  }_x000D_
}_x000D_
_x000D_
body:hover {_x000D_
  &::-webkit-scrollbar-thumb {_x000D_
    background-color: black;_x000D_
  }_x000D_
}_x000D_
_x000D_
.full-width {_x000D_
  width: 100%;_x000D_
  background: blue;_x000D_
  padding: 30px;_x000D_
  color: white;_x000D_
}
_x000D_
some content here_x000D_
_x000D_
<div class="full-width">does not change</div>
_x000D_
_x000D_
_x000D_


This will work:

#div{
     max-height:300px;
     overflow:hidden;
}
#div:hover{
     overflow-y:scroll;
}

.div::-webkit-scrollbar-thumb {
    background: transparent;
}

.div:hover::-webkit-scrollbar-thumb {
    background: red;
}

I think something like

$("#leftDiv").mouseover(function(){$(this).css("overflow","scroll");});
$("#leftDiv").mouseout(function(){$(this).css("overflow","hidden");});

The answer with changing overflow have a bunch of issues, like inconsistent width of the inner block and triggering of reflow.

There is an easier way to have the same effect that would not trigger reflow ever: using visibility property and nested blocks:

_x000D_
_x000D_
.scrollbox {_x000D_
  width: 10em;_x000D_
  height: 10em;_x000D_
  overflow: auto;_x000D_
  visibility: hidden;_x000D_
}_x000D_
_x000D_
.scrollbox-content,_x000D_
.scrollbox:hover,_x000D_
.scrollbox:focus {_x000D_
  visibility: visible;_x000D_
}_x000D_
_x000D_
.scrollbox_delayed {_x000D_
  transition: visibility 0.2s;_x000D_
}_x000D_
_x000D_
.scrollbox_delayed:hover {_x000D_
  transition: visibility 0s 0.2s;_x000D_
}
_x000D_
<h2>Hover it</h2>_x000D_
<div class="scrollbox" tabindex="0">_x000D_
  <div class="scrollbox-content">Hover me! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facere velit, repellat voluptas ipsa impedit fugiat voluptatibus. Facilis deleniti, nihil voluptate perspiciatis iure adipisci magni, nisi suscipit aliquam, quam, et excepturi! Lorem_x000D_
    ipsum dolor sit amet, consectetur adipisicing elit. Facere velit, repellat voluptas ipsa impedit fugiat voluptatibus. Facilis deleniti, nihil voluptate perspiciatis iure adipisci magni, nisi suscipit aliquam, quam, et excepturi!</div>_x000D_
</div>_x000D_
_x000D_
<h2>With delay</h2>_x000D_
<div class="scrollbox scrollbox_delayed" tabindex="0">_x000D_
  <div class="scrollbox-content">Hover me! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Facere velit, repellat voluptas ipsa impedit fugiat voluptatibus. Facilis deleniti, nihil voluptate perspiciatis iure adipisci magni, nisi suscipit aliquam, quam, et excepturi! Lorem_x000D_
    ipsum dolor sit amet, consectetur adipisicing elit. Facere velit, repellat voluptas ipsa impedit fugiat voluptatibus. Facilis deleniti, nihil voluptate perspiciatis iure adipisci magni, nisi suscipit aliquam, quam, et excepturi!</div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Another feature of this method is that visibility is animatable, so we can add a transition to it (see the second example in the pen above). Adding a transition would be better for UX: the scrollbar won't appear immediately when hovered just while moving along to another element, and it would be harder to miss the scrollbar when targeting it with mouse cursor, as it won't hide immediately as well.


This will help you to overcome overflow: overlay issues as well.

.div{
      height: 300px;
      overflow: auto;
      visibility: hidden;
    }

.div-content,
.div:hover {
  visibility: visible;
}