1

I have two divs one inside the other.

Both are explicitly set to the same height.

However the outer div has a max-width/height constraint and overflow auto.

This works as I want and the scrollbars come on when the divs are resized and the inner content dims exceed the outer divs.

Problem is that from that point reducing the size of both divs won't turn off the scrollbars.

Effectively one scrollbar is keeping the other scrollbar on.

The only work around so far has been to momentarily reduce the size of the inner div to 20px less than the outer div and then resetting it back to the matching dimensions.

Does anyone know of a solution that will stop the scrollbars staying 'on' when both inner and outer divs are the same size?

TIA Rob

demo hereJSFiddle

blackmamba
  • 757
  • 5
  • 21
  • 2
    Better provide some code OR at least create [demo](http://www.jsfiddle.net). – divy3993 Oct 23 '15 at 11:12
  • Make the inner div slightly larger than the containing div. Set the overflow on the outer div to hidden. Set the width on the inner div to ~110% – Jared Smith Oct 23 '15 at 11:34
  • Outer div needs overflow because the user has to be able to scroll the inner content to see it all when it is constrained. The outer div has a size constraint on it because of other UI elements. The outer div is being vertical and horizontally centered when less than its max values. – blackmamba Oct 23 '15 at 11:41
  • If the inner div is the only thing in the outer div, set the inner div to overflow: scroll, set the outer div to overflow: hidden, and make the inner div wider than its parent. User can scroll the inner div content by dragging, swiping (touchscreen), or mousewheel, but the scroll bars will not be visible. – Jared Smith Oct 23 '15 at 11:44
  • I actually do that fairly regularly because scrollbars can't really be styled and are IMHO ugly as sin. – Jared Smith Oct 23 '15 at 11:48
  • I need the scrollbar visible when it really is needed, its a requirement. I cant hide scrollbars and tell user to use mouse wheel as much as I would like to. FWIW there are other elements inside the outer div, various graphic overlays that fit exactly over the inner div. – blackmamba Oct 23 '15 at 11:52
  • 1
    In that case http://stackoverflow.com/questions/143815/determine-if-an-html-elements-content-overflows you will have to manually add a check for overflow each time the div content changes and selectively set the overflow property of the div to change on overflow. – Jared Smith Oct 23 '15 at 11:56
  • Yes that possible, although I was trying to avoid needing to do something like that if there was a CSS solution. – blackmamba Oct 23 '15 at 12:03
  • So it seems that using a setTimeout to flip the overflow value fails in the edge case where both the size of the two divs is the same and it is at the constrained value, although a browser should not show the scrollbars it does. This leaves no choice other than to manually track the div size and flip overflow when the size is 1px less than the size of the parent. – blackmamba Oct 24 '15 at 17:22

2 Answers2

2

This seems to be a problem when things are changed via script and the browser doesn't update the scrollbar position.

The trick here is to force a reflow by changing the overflow to auto again once your operations complete, and because it happens blazingly fast, to be able to get the browser recompute the need for scrollbars, you need to delay it a bit.

For example:

window.clickit = function (mode){
    switch(mode){
        case 1:
            ...
            outer.style.overflow = 'hidden';
            setTimeout(fixScroll, 100);
            break;
        case 2:
            ...
            outer.style.overflow = 'hidden';
            setTimeout(fixScroll, 100);
            break;
        case 3:
            ...
            outer.style.overflow = 'hidden';
            setTimeout(fixScroll, 100);
            break;
    }
}
function fixScroll() { outer.style.overflow = 'auto'; }

Demo Fiddle: http://jsfiddle.net/abhitalks/f9c8orf7/1/

Demo Snippet:

window.clickit = function (mode){
    switch(mode){
        case 1:
            outer.style.height='250px';
            outer.style.width='250px';
            inner.style.height='250px';
            inner.style.width='250px';
            outer.style.overflow = 'hidden';
            setTimeout(fixScroll, 100);
            break;
        case 2:
            outer.style.height='100px';
            outer.style.width='100px';
            inner.style.height='100px';
            inner.style.width='100px';
            outer.style.overflow = 'hidden';
            setTimeout(fixScroll, 100);
            break;
        case 3:
            outer.style.height='150px';
            outer.style.width='150px';
            inner.style.height='150px';
            inner.style.width='150px';
            outer.style.overflow = 'hidden';
            setTimeout(fixScroll, 100);
            break;
    }
}
function fixScroll() { outer.style.overflow = 'auto'; }
#outer{
    height: 150px; width: 150px;
    max-width:200px; max-height:200px;
    overflow:auto;
}
#inner {
    background-image: url('//lorempixel.com/200/200');
}
<div id="outer" style="height:150px;width:150px">
    <div id="inner" style="height:150px;width:150px"></div>
</div>
<button onclick="clickit(1);">bigger</button>
<button onclick="clickit(2);">smaller</button>
<button onclick="clickit(3);">reset</button>
Abhitalks
  • 27,721
  • 5
  • 58
  • 81
  • Yeah I like that, I reduced the timeout to 0 and it still works and doesn't appear to be noticeable. – blackmamba Oct 23 '15 at 12:07
  • @blackmamba: Yes, just a timeout should be enough. setTimeout stops the current execution context and gives opportunity for the browser to reflow/repaint, irrespective of time parameter. You could set it to zero. – Abhitalks Oct 23 '15 at 12:11
  • So it seems that using a setTimeout to flip the overflow value fails in the edge case where both the size of the two divs is the same and it is at the constrained value, although a browser should not show the scrollbars it does. – blackmamba Oct 24 '15 at 17:22
0

Change your CSS to:

#outer{
max-width:200px;
max-height:200px;
background-color:red;
overflow:hidden;

}

Brian
  • 127
  • 11
  • Overflow is needed on the outer div so that scrollbars DO show when the inner div is larger than the outer div. No scrollbars at all is not an option. I just need no scrollbars when the two div are the same size but scrollbars when the inner div is larger. – blackmamba Oct 23 '15 at 11:57