Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I expand a div so the overflow-y:auto scrollbar doesn't clip the div content?

Similar question, without a great answer:
How can I include the width of "overflow: auto;" scrollbars in a dynamically sized absolute div?

I have a <div> of fixed height that acts as a menu of buttons of uniform width. Users can add/remove buttons from the menu. When there are more buttons than can fit vertically in the <div>, I want it to become scrollable - so I'm using overflow-y:auto, which indeed adds a scrollbar when the content is too large in y. Unfortunately, when the scrollbar shows up it overlaps the menu buttons, and adds a horizontal scroll bar as a result - the big problem is it just looks horrible.

Is there a "right" way to fix this? I'd love to learn some style trick to make it work right (i.e. the scrollbar sits outside the div rather than inside, or the div automatically expands to accommodate the scroll bar when necessary). If javascript is necessary, that's fine - I'm already using jQuery - in that case, what are the right events are to detect the scrollbar being added/removed, and how do I make sure to use the correct width in a cross-browser/cross-style way?

JSFiddle: http://jsfiddle.net/vAsdJ/

HTML:
<button type="button" id="add">Add a button!</button>
<div id="menu">
</div>

CSS:
#menu{
    background:grey;
    height:150px;
    overflow-y:auto;
    float:left;
}

Script:
$('#add').button().click(function(){
    var d = $('<div/>');
    var b = $('<button type="button">Test</button>');
    d.appendTo($('#menu'));
    b.button().appendTo(d);
});
like image 791
tmpearce Avatar asked Nov 10 '22 13:11

tmpearce


1 Answers

First: To remove the horizontal scrollbar set overflow-x: hidden; as Trent Stewart has already mentioned in another answer.

CSS Approach:

One thing I have done in the past is to add a wider wrapping div around the content div to make room for the scrollbar. This, however, only works if your container width is fixed... and may need to be adjusted (by serving different styles) in various browsers due to variable rendering of scrollbars.

Here a jsfiddle for your case. Note the new wrapper <div id="menu-wrap"> and its fixed width width: 95px;. In this case the wrapper div is doing the scrolling.

You could probably also solve this by giving the wrapper some padding on the right, and thereby avoid the fixed width problem.


jQuery Approach:

Another option is to detect the overflow using jquery as described here, and then increasing the width or padding of the div to make space. You may still have to make browser-specific adjustments though.

Here a jsfiddle with a simplified version for your example. This uses your click function to check the div height after every click, and then adds some padding to make room for the scrollbar; a basic comparison between innerHeight and scrollHeight:

if($('#menu').innerHeight() < $('#menu')[0].scrollHeight){
    $('#menu').css( "padding", "0 15px 0 0" );
}

To make this more cross-browser friendly you could check for the scrollbar width (as outlined here) and then add the returned value instead of the fixed padding. Here another jsfiddle to demonstrate.


There are probably many other methods, but this is how I would go about it.

like image 181
pschueller Avatar answered Nov 15 '22 03:11

pschueller