Search code examples
cssfirefoxflexboxsticky-footer

Sticky footer with flexbox on body and children


I want to use a simple flexbox layout with header, section (consisting of aside and section) and a sticky footer.

My problem is, that when I apply display:flex to the body and to at minimum one child (it doesn't matter if it's header, section or footer) only firefox does it like I need to.

html, body {
	height:100vh;
	min-height: 100vh;
}

body {
	display: flex;
	flex-direction: column;
}

section {
	flex: 1;
	display: flex;
}
section section {
	display: block;
}
<body>

	<header>
		<h1>Test Flexbox</h1>
	</header>
  
	<section>
	  <aside>
	  <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
	</aside>
    
	  <section>
		<article>
          <h2>Test</h2>
          <p>Welome to this flex box test snippet.</p>
        </article>
      </section>
    
  </section>

	<footer>
		<p>Here goes the footer, that should always stick to the bottom</p>
	</footer>

</body>

The above code works in Firefox but does not work in Chrome, Opera, Safari (and probably more).

If I apply the display:flex to a <div> after the body instead, it works everywhere.

Is this a bug or is it not allowed/recommended to use flexbox on the body-element?

EDIT: Here is the alternative-version using a div which works in all browsers:

html, body {
	height:100vh;
	min-height: 100vh;
}

div {
	display: flex;
	flex-direction: column;
}

section {
	flex: 1;
	display: flex;
}
section section {
	display: block;
}
<body><div>

	<header>
		<h1>Test Flexbox</h1>
	</header>
  
	<section>
	  <aside>
	  <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
      <p>Test Test Test</p>
	</aside>
    
	  <section>
		<article>
          <h2>Test</h2>
          <p>Welome to this flex box test snippet.</p>
        </article>
      </section>
    
  </section>

	<footer>
		<p>Here goes the footer, that should always stick to the bottom</p>
	</footer>

</div></body>


Solution

  • When using viewport units, no need to set it on all items, in this case the body is enough. Also, drop the height: 100vh and it will work fine.

    Note 1; the div version works, kind of, but not fully either, because you didn't gave it height/min-height as the body has.

    Note 2; I read somewhere that when using both height/min-height with the same value, it could go wrong/be buggy in some browsers, which might be the case here. When I find where it was, I'll update my answer.

    Stack snippet

    body {
      display: flex;
      flex-direction: column;
      min-height: 100vh;
    }
    
    section {
      flex: 1;
      display: flex;
    }
    
    section section {
      display: block;
    }
    <header>
      <h1>Test Flexbox</h1>
    </header>
    
    <section>
      <aside>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
      </aside>
    
      <section>
        <article>
          <h2>Test</h2>
          <p>Welome to this flex box test snippet.</p>
        </article>
      </section>
    
    </section>
    
    <footer>
      <p>Here goes the footer, that should always stick to the bottom</p>
    </footer>


    Updated; to support IE11, which has a min-height bug, do like this:

    html {
      display: flex;                   /*  IE bug fix  */
    }
    
    body {
      width: 100%;                     /*  flex row item need this to
                                           take full width  */
      display: flex;
      flex-direction: column;
      min-height: 100vh;
    }
    
    section {
      flex-grow: 1;                    /*  IE need this  */
      display: flex;
    }
    
    section section {
      display: block;
    }
    <header>
      <h1>Test Flexbox</h1>
    </header>
    
    <section>
      <aside>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
        <p>Test Test Test</p>
      </aside>
    
      <section>
        <article>
          <h2>Test</h2>
          <p>Welome to this flex box test snippet.</p>
        </article>
      </section>
    
    </section>
    
    <footer>
      <p>Here goes the footer, that should always stick to the bottom</p>
    </footer>