Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fill remaining vertical space with CSS using display:flex

In a 3-row layout:

  • the top row should be sized according to its contents
  • the bottom row should have a fixed height in pixels
  • the middle row should expand to fill the container

The problem is that as the main content expands, it squishes the header and footer rows:

Flexing Bad

section {   display: flex;   flex-flow: column;   align-items: stretch;   height: 300px; } header {   flex: 0 1 auto;   background: tomato; } div {   flex: 1 1 auto;   background: gold;   overflow: auto; } footer {   flex: 0 1 60px;   background: lightgreen;   /* fixes the footer: min-height: 60px; */ }
<section>   <header>     header: sized to content     <br>(but is it really?)   </header>   <div>     main content: fills remaining space<br>     x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>     <!-- uncomment to see it break - ->     x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>     x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>     x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>     x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>     <!-- -->   </div>   <footer>     footer: fixed height in px   </footer> </section>

Fiddle:

  • http://jsfiddle.net/7yLFL/1/ (working, with small content)
  • http://jsfiddle.net/7yLFL/ (broken, with larger content)

I'm in the lucky situation that I can use the latest and greatest in CSS, disregarding legacy browsers. I thought I could use the flex layout to finally get rid of the old table-based layouts. For some reason, it's not doing what I want...

For the record, there are many related questions on SO about "filling the remaining height", but nothing that solves the problem I'm having with flex. Refs:

  • Make a div fill the height of the remaining screen space
  • Fill remaining vertical space - only CSS
  • Have a div to fill out the remaining height/width of a container when sharing it with another div?
  • Make nested div stretch to 100% of remaining container div height
  • How can I make my flexbox layout take 100% vertical space?
  • etc
like image 587
Zilk Avatar asked Aug 02 '14 18:08

Zilk


People also ask

How do I fill the remaining space on my flexbox?

You can use the flex-grow property to force an item to fill the remaining space on the main axis of a flex container. The item will expand as much as possible and occupy the free area.

How do I fill a remaining space in CSS?

The width property is used to fill a div remaining horizontal space using CSS. By setting the width to 100% it takes the whole width available of its parent. Example 1: This example use width property to fill the horizontal space. It set width to 100% to fill it completely.

How do I get my flex to grow vertically?

You should set height of html, body, . wrapper to 100% (in order to inherit full height) and then just set a flex value greater than 1 to . row3 and not on the others.


1 Answers

Make it simple : DEMO

section {    display: flex;    flex-flow: column;    height: 300px;  }    header {    background: tomato;    /* no flex rules, it will grow */  }    div {    flex: 1;  /* 1 and it will fill whole space left if no flex value are set to other children*/    background: gold;    overflow: auto;  }    footer {    background: lightgreen;    min-height: 60px;  /* min-height has its purpose :) , unless you meant height*/  }
<section>    <header>      header: sized to content      <br/>(but is it really?)    </header>    <div>      main content: fills remaining space<br> x      <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>      <!-- uncomment to see it break -->      x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x      <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x      <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x      <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>      <!-- -->    </div>    <footer>      footer: fixed height in px    </footer>  </section>

Full screen version

section {    display: flex;    flex-flow: column;    height: 100vh;  }    header {    background: tomato;    /* no flex rules, it will grow */  }    div {    flex: 1;    /* 1 and it will fill whole space left if no flex value are set to other children*/    background: gold;    overflow: auto;  }    footer {    background: lightgreen;    min-height: 60px;    /* min-height has its purpose :) , unless you meant height*/  }    body {    margin: 0;  }
<section>    <header>      header: sized to content      <br/>(but is it really?)    </header>    <div>      main content: fills remaining space<br> x      <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>      <!-- uncomment to see it break -->      x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x      <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x      <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br> x      <br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>      <!-- -->    </div>    <footer>      footer: fixed height in px    </footer>  </section>
like image 192
G-Cyrillus Avatar answered Oct 21 '22 10:10

G-Cyrillus