0

I'm trying to have a basic HTML page, split three way, top and bottom panes should have a fixed fix, or autosize, and middle should fill the remaining.

I got it working once using position:fixed, but that is very ugly and doesn't work once things get more dynamic.

I finally got this to work on Chrome using tables and making the height:100% in the middle tr. I celebrated, then tried Firefox, and it does not work.

Here is the fiddle, https://jsfiddle.net/b1uxcupv/6/

HTML is basically,

<html style="height:100%;width:100%;max-height:100%">
<body style="height:100%;width:100%;">
    <table style="height:100%;width:100%;">
        <tr><td style="height:50px;width:100%;background-color:blue"></td></tr>
        <tr><td style="height:100%;width:100%;background-color:grey">
            <div style="overflow:auto;height:100%">
                blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>
                blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>
                blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>
                blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>
            </div>
        </td></tr>
        <tr><td style="height:50px;width:100%;background-color:green"></td></tr>
    </table>
</body>
<html>

I have basically two versions of this, one the page should fill the browse window with the middle pane taking all the extra room and scrolling if required.

The second is basically the same but the whole thing is in a fixed sized div inside a page. Both work on Chrome, but Firefox does not give the scrollbar in the middle pane, it just ignores the max-size and keeps filling the page.

Cœur
  • 37,241
  • 25
  • 195
  • 267
James
  • 17,965
  • 11
  • 91
  • 146

3 Answers3

1

Here's probably the easiest, modern way of handling it.

HTML

<div class="container">
  <div class="head"></div>
  <div class="mid"></div>
  <div class="foot"></div>
</div>

CSS

.container {
  display:flex;
  flex-direction:column;
  height:100vh;
  width:100%;
}
.head {
  background:blue;
  min-height:100px;
}
.mid {
  background:#eee;
  overflow:auto;
  flex-grow:1;
}
.foot {
  background:green;
  min-height:100px;
}
kthornbloom
  • 3,660
  • 2
  • 31
  • 46
  • tried it, and it does not work, maybe if you post a fiddle like https://jsfiddle.net/b1uxcupv/15/ the key point is the middle needs to scroll its content if bigger than its space – James Aug 11 '16 at 21:08
  • Oh ok, just need "overflow:auto" then. Try this: http://jsfiddle.net/b1uxcupv/16/ – kthornbloom Aug 12 '16 at 01:39
  • wonderful, this seems to work, will need to do some more testing, thanks – James Aug 13 '16 at 10:53
  • 1
    @James - Sounds good! Mind accepting this if it's working for you? – kthornbloom Aug 17 '16 at 18:23
0

Okay I found a solutions... but is requires JavaScript, which I am finding required to layout things correctly in a web app, CSS really needs to support dynamic web app layouts better.

Here it is, https://jsfiddle.net/b1uxcupv/15/

<html style="width:100%;height:100%;">
<body style="height:100%;width:100%;padding:0;margin:0">
    <table style="height:100%;width:100%;">
        <tr><td style="height:50px;width:100%;background-color:blue"></td></tr>
        <tr><td style="height:100%;width:100%;background-color:grey">
            <div id="scroller" style="max-height:100px;overflow:auto;height:100%">
                xxblah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>
                blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>
                blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>
                blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>blah<br/>
            </div>
        </td></tr>
        <tr><td style="height:50px;width:100%;background-color:green"></td></tr>
    </table>
    <script>
        var scroller = document.getElementById('scroller');
        console.log(scroller);
        console.log(scroller.parentNode);
        console.log(scroller.parentNode.offsetHeight);
        scroller.style.maxHeight = scroller.parentNode.offsetHeight + "px";
        var reset = true;
        window.onresize = function() {
            console.log(scroller.parentNode.offsetHeight - 4);
            scroller.style.maxHeight = "100px";
            if (reset) {
                reset = false;
                setTimeout(function() {
                    reset = true;
                    scroller.style.maxHeight = scroller.parentNode.offsetHeight + "px";
                }, 100);
            }
        };
    </script>
</body>

Basically I set a max-height on the middle scroller to something smallish (100px) then is JavaScript resize the maxHeight to the parent's offestHeight, and register for resize events.

Perhaps not pretty, but it works Chrome, Firefox, IE, and Safari.

I still think there must be a css solution that does not require JavaScript or position:fixed, and works on more than just Chrome. Anybody got an idea?

Thanks for the users who submitted answers, they were good attempts, but did not fill the window, or used static fixed positions.

James
  • 17,965
  • 11
  • 91
  • 146
-1

Based on this SO and this SO, it seems like <td> does not support the overflow attribute. Placing a <div> within the <td>, and also setting a fixed height for the <td> but a height:100% for the <div> got it working for me. Any tag with an overflow attribute should either have a fixed height or be nested within another tag with a fixed height.

Here is my fiddle that works in Chrome and Firefox: https://jsfiddle.net/rgutierrez1014/b1uxcupv/13/

Community
  • 1
  • 1
rgutierrez1014
  • 396
  • 4
  • 9
  • This does not work, the middle must fill the browser window 100%, having a fixed height is no good. – James Mar 12 '15 at 01:36
  • If you look at the code and example in Chrome it fills the window and scrolls the middle pane. Both are required. – James Mar 12 '15 at 01:39