How to do a sticky footer and still be able to do scrollable flexbox content?
Asked Answered
E

1

0

I'm trying to achieve the sticky footer (flexbox version). However, I'm unable to find a working solution if I also want the ability to have scrollable content inside a flex: 1 div (which requires parents to have height: 100%).

Here's a fiddle to demonstrate the problem: https://jsfiddle.net/gfaqLh42/6/

enter image description here

As you can see, the red area is scrollable (with a min-height: 300px). Notice the footer is offscreen even though the viewport is not less than the red area's min-height + blue area.

Is there a way to do a sticky footer and still use flexbox flex: 1 with scrollable content?

Update

Here's another picture to represent the other big problem I face in trying to make this work:

enter image description here

Edy answered 31/1, 2018 at 5:50 Comment(0)
R
2

Is there a way to do a sticky footer and still use flexbox flex: 1 with scrollable content?

Yes, and what you need is to use Flexbox all the way.

So instead of using min-height/height on article-1/card, change their CSS to this:

.article-1 {
  flex: 1;
  display: flex;
  min-height: 0;                     /*  added, i.a Firefox need this  */
}

.card {
  overflow: auto;
}

Note, I also remove some properties not needed, mainly as they were set to their defaults, and added some. And why the need of min-width, is well explained here:

Updated fiddle

Stack snippet

html, body{
  height: 100%;
  margin: 0;
  font-weight: bold;
}

.header {
  position: absolute;
  height: 40px;
  background-color: grey;
  z-index: 1;
  width: 100%;
}

.content {
  display: flex;
  flex-direction: column;
  height: 100%;  
  padding-top: 40px;
  box-sizing: border-box;            /*  added  */
}

.wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;                     /*  added, i.a Firefox need this  */
}

.container {
  flex: 1;
  padding: 10px;
  box-sizing: border-box;            /*  added  */
  display: flex;
  flex-direction: column;
  min-height: 0;                     /*  added, i.a Firefox need this  */
}

.article-1 {
  flex: 1;
  display: flex;
  min-height: 0;                     /*  added, i.a Firefox need this  */
}

.card {
  overflow: auto;
}

.card-text {
  height: 2000px;
  width: 2000px;
  background-color: red;
}

.article-2 {
  flex: none;
  height: 40px;
  background-color: blue;
}

.footer {
  position: relative;
  height: 40px;
  background-color: grey;
}
<div class="header">Header</div>
<div class="content">

  <div class="wrap">
    <div class="container">
      <div class="article-1">
        <div class="card">
          <div class="card-text">
            scrollable flex: 1 div<br>
            1. scrollable<br>
            2. scrollable<br>
            3. scrollable<br>
            4. etc...
          </div>
        </div>
      </div>
      <div class="article-2">
        flex: none div
      </div>
    </div>
  </div>

  <div class="footer">Footer</div>
</div>

Updated based on a comment

If there is a need for the article-1 to have a minimum height, and to avoid absolute positioning on it, a minimum height could be set on content as well, to push the footer further down on smaller screens.

Updated fiddle 2

Stack snippet

html, body{
  height: 100%;
  margin: 0;
  font-weight: bold;
}

.header {
  position: absolute;
  height: 40px;
  background-color: grey;
  z-index: 1;
  width: 100%;
}

.content {
  display: flex;
  flex-direction: column;
  height: 100%;  
  min-height: 450px;                 /*  added  */
  padding-top: 40px;
  box-sizing: border-box;            /*  added  */
}

.wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;                     /*  i.a Firefox need this  */
}

.container {
  flex: 1;
  padding: 10px;
  box-sizing: border-box;            /*  added  */
  display: flex;
  flex-direction: column;
  min-height: 0;                     /*  i.a Firefox need this  */
}

.article-1 {
  flex: 1;
  display: flex;
  min-height: 300px;                 /*  changed  */
}

.card {
  overflow: auto;
}

.card-text {
  height: 2000px;
  width: 2000px;
  background-color: red;
}

.article-2 {
  flex: none;
  height: 40px;
  background-color: blue;
}

.footer {
  position: relative;
  height: 40px;
  background-color: grey;
}
<div class="header">Header</div>
<div class="content">

  <div class="wrap">
    <div class="container">
      <div class="article-1">
        <div class="card">
          <div class="card-text">
            scrollable flex: 1 div<br>
            1. scrollable<br>
            2. scrollable<br>
            3. scrollable<br>
            4. etc...
          </div>
        </div>
      </div>
      <div class="article-2">
        flex: none div
      </div>
    </div>
  </div>

  <div class="footer">Footer</div>
</div>
Retire answered 31/1, 2018 at 7:4 Comment(7)
This is really close! The only problem is if you have min-height: 300px on article-1 and resize the viewport down the footer does not push down like a sticky footer should (even though it is relative!, so weird!). Instead of pushing down, it stays at the same position as the other divs push further down (the footer actually becomes higher than those other divs). Article-1 needs a min-height (more than 0) because otherwise that div squishes too small to be usable on smaller screens.Edy
See second image in "update" section of my question.Edy
@Edy To fix that, and enable a min-height: 300px on article-1, you could also give a min-width to content, e.g. 450px: jsfiddle.net/gfaqLh42/9 ... Will that work for you?Retire
@Edy The main problem here is, and for the inner scroll to work, a height is needed, so one can't set a min-height on the outer elements, like the html/body either. The best option is the suggestion with a min-height on content, or else the scroll element needs to be positioned absolute.Retire
@Edy I updated my answer with a sample of my suggestion.Retire
Yeah, setting a min-height: 450px (enough to cover the min-height needs of that scrollable div) worked! Your second fiddle is great. The footer acts sticky and moves down when I shrink the viewport to force scrolling it. Thank you.Edy
Even though this solution worked, having to set the min-height on the content to different values based on certain pages was messy. I eventually just include the footer component at the bottom of each page template/component so that I can include it in a flex box along with the other flex boxes above it on the page. But your other adjustments still helped me a lot and my understanding too!Edy

© 2022 - 2024 — McMap. All rights reserved.