The layout I am trying to achieve is like this, exactly filling the entire viewport of the browser:
[----fixed height top "menu bar"----]
/-----\/----------------------------\
|fixed|| |
|width|| both ways stretchy content |
|side || |
|bar || |
\-----/\----------------------------/
I have it nearly working, but I haven't figured out how to specify that the horizontally-arranged boxes vertically fill the space available to them rather than the height of the page. As it currently stands, whenever the content in the sidebar is long enough to cause it to gain a scroll bar, I end up with an additional vertical scrollbar on the entire page which scrolls by exactly the height of the top bar, which is not what I want.
The following 1998-styled demo page illustrates the problem. It actually produces the layout I want in Safari 9, but not Chrome or Firefox.
Note these additional constraints, which are already satisfied by the demo and must be preserved:
There may be an arbitrary number of fixed-width or stretchy boxes arranged in the horizontal direction.
Each side bar or main content has an
overflow-y: auto
vertical scrollbar. This must also work (that is, long content must not make the overall flexbox layout exceed the viewport size). Some of the sidebars themselves use flexbox layout in the vertical direction.A 90%-10% layout is not suitable for the purpose. Nor is allowing some of the content to be clipped. The entire reason I have this layout problem is that the application should be using every pixel of the screen to show useful information or controls, so any extra whitespace or clipped content is undesirable.
<!doctype html>
<html style="height: 100%;">
<title>Flexbox test</title>
<style type="text/css">
#parent-of-topbar {
height: 100%; box-sizing: border-box; margin: 0;
background: #FCC;
display: flex; flex-direction: column;
}
#topbar {
padding: .2em;
background: white;
border: solid black;
border-width: 0 0 .3em 0;
color: black;
flex: 0 0 auto;
}
#main {
display: flex; flex-direction: row;
flex: 1 1 auto;
max-height: 100%;
}
.subwindow {
overflow-x: clip;
overflow-y: auto;
max-height: 100%;
border: 3px outset #CCC;
background: linear-gradient(to right, #CCC 0%,#AAA 100%);
}
.fixed {
flex: 0 0 auto;
width: 10em;
}
.stretchy {
flex: 1 1 auto;
width: 100%;
}
</style>
<body id="parent-of-topbar">
<div id="topbar">top bar content</div>
<div id="main">
<div class="subwindow stretchy">stretchy part</div>
<div class="subwindow fixed">
fixed sidebar 1; this should be scrollable, not stretch the content
<details open><div style="font-size: 3em;">spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam spam</div></details>
</div>
<div class="subwindow fixed">
2nd fixed sidebar
</div>
</div>
</body>
Here is a screenshot of the layout I want to achieve, faked by hardcoding a dimension:
Here is a screenshot of the layout the current demo gets on Chrome: