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

prograhammer
  • 20,132
  • 13
  • 91
  • 118

1 Answers1

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>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • 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. – prograhammer Jan 31 '18 at 16:44
  • See second image in "update" section of my question. – prograhammer Jan 31 '18 at 16:49
  • @prograhammer To fix that, and enable a `min-height: 300px` on `article-1`, you could also give a `min-width` to `content`, e.g. 450px: https://jsfiddle.net/gfaqLh42/9/ ... Will that work for you? – Asons Jan 31 '18 at 16:53
  • 1
    @prograhammer 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. – Asons Jan 31 '18 at 16:56
  • @prograhammer I updated my answer with a sample of my suggestion. – Asons Jan 31 '18 at 17:08
  • 1
    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. – prograhammer Jan 31 '18 at 19:03
  • 1
    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! – prograhammer Jan 31 '18 at 19:47