21

Given this div:

<div style="overflow:auto;"></div>

How can I make the scrollbars visible only when the mouse is over the div?

I don't want the scrollbars to always appear. Facebook's right-top corner is an example of this.

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
Utku Dalmaz
  • 9,780
  • 28
  • 90
  • 130

8 Answers8

34

You can make overflow hidden until the mouse is over it, then make it auto. This is what I did ... note the 16px padding assumes a scrollbar is 16px wide, and is there so the text doesn't re-wrap when the scrollbar appears.

    div.myautoscroll {
        height: 40ex;
        width: 40em;
        overflow: hidden;
        border: 1px solid #444;
        margin: 3em;
    }
    div.myautoscroll:hover {
        overflow: auto;
    }
    div.myautoscroll p {
        padding-right: 16px;
    }
    div.myautoscroll:hover p {
        padding-right: 0px;
    }

See it in action at this fiddle - you'll want to widen the right side "result" window to see the whole box, or reduce the width in the css.


Edit 2014-10-23

There is now more variation in how systems and browsers display scrollbars, so my 16px space may need to be adjusted for your case. The intent of that padding is to prevent the text from being re-flowed as the scrollbar appears and disappears.

Some systems, such as newer versions of Mac OS X (10.8.x at least), don't show scrollbars until you start scrolling which could throw this whole technique off. If the scrollbar doesn't show you may have no reason to hide it until hover, or you may want to leave overflow as auto or even scroll rather than toggling it.

Stephen P
  • 14,422
  • 2
  • 43
  • 67
  • Thanks for the solution. I needed it for one of my job. But I've a small issue. The 16px padding-right that you have used when there is no visible scrollbar and it becomes 0 on hover when the scrollbar is visible. I don't want to use the 16px padding for some reason, so I removed it. First time it works fine, hovering over the div brings the scrollbar, hovering out removes it but there is a 16px(I assume) gap left. I don't know where is the gap coming from. Please find the fiddle here http://jsfiddle.net/9scJE/ – Rupam Datta Apr 10 '13 at 05:18
  • I did this code to show the scrollbar, not sure why had to put scroll instead of just auto, but that's how it worked, however not sure why when i hover over the area it only shows the scrollbar when i scroll and not when i just hover/mouse over the div area `#myautoscroll { max-height: 200px; overflow-y: hidden; } #myautoscroll:hover { overflow-y: scroll; }` – nommer Oct 23 '14 at 18:27
21

The answer with changing overflow have a bunch of issues, like inconsistent width of the inner block, triggering of reflow, the need to have extra code for deal with paddings and without disabling keyboard (and, possibly, other) interactions when not hovered.

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

.scrollbox {
  width: 10em;
  height: 10em;
  overflow: auto;
  visibility: hidden;
}
.scrollbox-content,
.scrollbox:hover {
  visibility: visible;
}

Here is a pen with a working example: http://codepen.io/kizu/pen/OyzGXY

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.

kizu
  • 42,604
  • 4
  • 68
  • 95
  • 2
    This approach worked well for me, and it's good that it doesn't mess with the overflow property (and all the issues you allude to there). But the animation on it doesn't work. It seems that visibility can't animate (https://stackoverflow.com/questions/27900053/css-transition-with-visibility-not-working). Opacity can animate but when I use that in this setup, then the content within .scrollbox-content is also affected by the opacity (the content fades out with the scrollbar). Have you gotten the animation part to work with this approach? – Rebecca Feb 06 '16 at 07:17
  • 1
    @rebecca Visibility is either on or off. I Believe what kizu meant is that you can use the delay property associated with the transition. One of the examples has a 200ms delay before showing or hiding the scrollbars. Brilliant solution, kizu. This solves the problem nicely. – James May 15 '18 at 17:42
  • Give them a medal. And then another one. A very clean solution! – user35443 Jul 25 '18 at 13:55
  • 1
    Weird solution - why doesn't visibility: hidden; affect the scrollbox div? Why isn't it hidden? – GeForce RTX 4090 Feb 05 '20 at 15:48
  • 2
    @gfels This is how visibility works: unlike most other properties it is possible to “restore” the visibility on the elements inside. – kizu Feb 06 '20 at 16:14
6

Try selecting the div with :hover selector

#div { overflow: hidden; }

#div:hover { overflow:visible; }
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
Philip Kirkbride
  • 21,381
  • 38
  • 125
  • 225
1

I have had the same problem and tried a bunch of the above solutions without result. After lots of research I came to this solution. Just paste these lines into your css file.

div.myautoscroll {
    height: 40ex;
    width: 40em;
    overflow: hidden;
    border: 1px solid #444;
    margin: 3em;
}
div.myautoscroll:hover {
    overflow: auto;
}
div.myautoscroll p {
    padding-right: 16px;
}
div.myautoscroll:hover p {
    padding-right: 0px;
}


::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 7px;
}

::-webkit-scrollbar-thumb {
    border-radius: 4px;
    background-color: rgba(0,0,0,.5);
    -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}

What was happening to me was that Mac OSX lion and up (I am running Yosemite) auto hide scrollbars to seem more sleek. The code above overwrites the default and brings back the scrollbar ... combined with the css for changing the overflow to scroll on hover this will achieved the desired result for users on the newer mac OSXs. Here is a fiddle (not my own but the one where I found this answer). http://jsfiddle.net/simurai/UsvLN/

Benjamin Conant
  • 1,684
  • 1
  • 14
  • 17
0

I came up with this solution. Basically the negative margin cuts off the vertical scrollbar.

.hidden-scrollbar {
    padding-right: 50px;
    margin-right: -25px;        
    overflow-y: auto;        
}

.hidden-scrollbar.hover-scrollbar:hover {
    padding-right: 25px;
    margin-right: 0;
    overflow-y: auto;
}

LESS mixin

.hidden-scrollbar(@padding) {
    padding-right: 2 * @padding;
    margin-right: -@padding;
    overflow-y: auto;        

    &.hover-scrollbar:hover {
        padding-right: @padding;
        margin-right: 0;
    }
}

NOTE: @padding should be at least the scrollbar width (e.g. 25px)

Basically add this to your LESS/CSS and add the class to the element that needs it's scrollbar cut off.

It's me ... Alex
  • 279
  • 4
  • 11
0

How about this, rather than moving margins/padding or visibility, just make the color transparent and restore it on the hover.

.mydiv::-webkit-scrollbar-track{
    background-color: transparent;
}
.mydiv::-webkit-scrollbar-thumb{
    background-color: transparent;
}
.mydiv:hover::-webkit-scrollbar-thumb{
    background-color: #a0a0a0;
}
.mydiv:hover::-webkit-scrollbar-track{
    background-color: #e1e1e1;
}
-1

If you can use css to add overflow-y hidden in the normal view.Then you can add the :hover event add overflow-y:auto.

See This Link


If you can use Jquery use the hover event

See This Fiddle


Snippet:

jQuery(".main_panel").hover(
  function() {
    jQuery(this).addClass("show_cont");
  },
  function() {
    jQuery(this).removeClass("show_cont");
  }
);
.main_panel {
  width: 300px;
  height: 200px;
  display: block;
  position: relative;
  margin: 0 auto;
  overflow: hidden;
}

.limt {
  padding: 0;
  display: inline-block;
  width: 90%;
  margin: 0;
}

ul.limt li {
  display: inline-block;
  width: 100%;
  font-size: 18px;
  line-height: 28px;
}

.show_cont {
  overflow-y: auto;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<div class="main_panel">
  <ul class="limt">
    <li>Curabitur aliquet quam id dui posuere blandit.</li>
    <li>Curabitur aliquet quam id dui posuere blandit.</li>
    <li>Curabitur aliquet quam id dui posuere blandit.</li>
    <li>Curabitur aliquet quam id dui posuere blandit.</li>
    <li>Curabitur aliquet quam id dui posuere blandit.</li>
  </ul>
</div>
Community
  • 1
  • 1
-1

Try this CSS hack!.

.c-scroller {
  overflow: hidden;
  height: 90vh
}
.c-scroller-content,
.c-scroller:hover,
.c-scroller:focus {
  overflow: auto;
}
<div class="c-scroller">
    Item 1<br />
    Item 2<br />
    Item 3<br />
    Item 4<br />
    Item 5<br />
    Item 6<br />
    Item 7<br />
    Item 8<br />
    Item 9<br />
    Item 10<br />
    Item 11<br />
    Item 12<br />
    Item 13<br />
    Item 14<br />
    Item 15<br />
    Item 16<br />
    Item 17<br />
    Item 18<br />
    Item 19<br />
    Item 20<br />
    Item 21<br />
    Item 22<br />
    Item 23<br />
</div>
Saddam
  • 1,174
  • 7
  • 14