Jan Vladimir Mostert
Jan Vladimir Mostert

Reputation: 12972

Add fixed footer inside content that's already bounded by page-level header and footer

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:

enter image description here

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.

enter image description here

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

Answers (1)

Asons
Asons

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.

Fiddle demo

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

Related Questions