Reputation: 12972
I'm using flexbox to build a layout; getting a page-level header and footer to stay in place is fairly easy and so is getting the area between the header and footer to display columns.
<div class="vbox fill" >
<header class="header">
</header>
<div class="hbox expand no-padding no-margin">
<div class="column1 vbox"></div>
<div class="column2 vbox"></div>
<div class="content vbox">
Content Here
</div>
<div class="column4 vbox"></div>
<div class="column5 vbox"></div>
</div>
<footer class="footer">
</footer>
</div>
CSS:
.vbox {
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
}
.hbox {
display: flex;
flex-direction: row;
margin: 0;
padding: 0;
}
.expand {
flex: 1 1 100%;
width: 100%;
height: 1%;
}
.fill {
height: 100vh;
}
Now I'm trying to display content, but have a "footer" inside the content that remains in place:
I've managed to get a red footer in there while the yellow content fills up the rest of the screen, but when the yellow div expands due to too much data, it pushes the red div out of the screen with a a scrollbar.
This is what I've done so far (this html now sits where the Content Here
section is)
CSS:
.row1 {
flex: 1 1 auto;
background-color: yellow;
}
.row2 {
flex: 0 0 50px;
background-color: red;
}
HTML:
<div class="row1" *contentItem>
TEST1
</div>
<div class="row2" *contentItem>
TEST2
</div>
The yellow div should obviously be constrained to a certain height, but how much should I set it to? 100vh
is not an option since the yellow and red divs are bounded by a header and footer and 100vh
simply make the yellow div the same size as the page not taking into account the page-level header and footer which also scrolls the red bar out of view.
Any ideas on how to keep the red div from being pushed off-screen when the yellow div expands?
EDIT:
This hack seems to make it work, not sure why the 1% thing makes it work:
.row1 {
flex: 1 1 auto;
overflow: auto;
height: 1%;
}
.row2 {
flex: 0 0 auto;
}
Upvotes: 0
Views: 145
Reputation: 87191
Trying to understand you but am not fully sure, so wondering if this is what you are looking for?
What I did was to add the 2 new elements (row1
/row2
) to your initial content
element, though I called them content-main
and content-footer
.
Then I gave content-main
flex-grow: 1
so it fills remaining what's left after content-footer
take its space.
Finally, to avoid that the content-footer
gets pushed away, I added an inner element, content-scroller
using absolute positioning.
The inner content-scroller
shouldn't be necessary, though all browsers but Chrome is not okay with simply setting overflow: auto
on the content-main
, so to make it work on all, that extra element is needed.
The good part is, it doesn't affect the solution in any negative way when it comes to responsiveness etc.
Stack snippet
html, body {
margin: 0;
}
.vbox {
display: flex;
flex-direction: column;
}
.hbox {
display: flex;
flex-direction: row;
}
.expand {
flex-grow: 1;
width: 100%;
}
.expand .content {
flex-grow: 1;
}
.expand .content .content-main {
position: relative;
flex-grow: 1;
background: lime;
}
.expand .content .content-main .content-scroller {
position: absolute;
left: 0; top: 0;
height: 100%; width: 100%;
background: yellow;
overflow: auto;
}
.expand .content .content-footer {
background: red;
}
.fill {
height: 100vh;
}
<div class="vbox fill">
<header class="header">
Header
</header>
<div class="hbox expand no-padding no-margin">
<div class="column1 vbox"> Col 1 </div>
<div class="column2 vbox"> Col 2 </div>
<div class="content vbox">
<div class="content-main">
<div class="content-scroller">
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
Content Here<br>
</div>
</div>
<div class="content-footer">
Content Footer
</div>
</div>
<div class="column4 vbox"> Col 4 </div>
<div class="column5 vbox"> Col 5 </div>
</div>
<footer class="footer">
Footer
</footer>
</div>
Upvotes: 1