20

I have a page that has a header, content, and footer. The header and footer are of fixed height, and I'd like the content to adjust its height so that it fits dynamically between the header and footer. I am planning to put a background-image in my content, so it is critical that it actually fills the rest of the unoccupied vertical space.

I used the Sticky Footer approach to ensure that the footer remains on the bottom of the page. This however does not make the content span the entire height of the remaining space.

I have tried several solutions which involved me adding height:100%, height:auto; position:relative but it did not work.

html,
body {
  height: 100%;
  background-color: yellow;
}
header {
  width: 100%;
  height: 150px;
  background-color: blue;
}
header nav ul li {
  display: inline;
  padding: 0 30px 0 0;
  float: left;
}
#wrapper {
  min-height: 100%;
  height: auto !important;
  height: 100%;
  margin: 0 0 -30px 0;
  /* the bottom margin is the negative value of the footer's height */
  position: relative;
}
#wrapper #content {
  background-color: pink;
  width: 400px;
  height: 100%;
  margin: 0 0 -30px 100px;
  padding: 25px 30px 25px 30px;
}
footer {
  margin: -30px 0 0 0;
  width: 100%;
  height: 30px;
  background-color: green;
}
<div id="wrapper">

  <header>
    <div id="logo"></div>

    <nav>
      <ul>
        <li>About</li>
        <li>Menu</li>
        <li>Specials</li>
      </ul>
    </nav>
  </header>

  <div id="content">
    content
    <br>goes
    <br>here
  </div>

</div>

<footer>footer</footer>
Ruslan López
  • 4,433
  • 2
  • 26
  • 37
Jon
  • 2,249
  • 6
  • 26
  • 30
  • This is possibly a duplicate of [How to make a div expand to fit available vertical space?](http://stackoverflow.com/questions/2351674/how-to-make-a-div-expand-to-fit-available-vertical-space) – ccpizza May 05 '12 at 18:44
  • It might work if you set `height:100%` for both `html` and `body` tags. – ccpizza May 05 '12 at 18:52

6 Answers6

9

I'm providing a slightly more general solution so it is more useful for others reading this answer and wondering how to apply it to their site.

Assuming you have three divs:

<div id='header'></div>
<div id='contents'></div>
<div id='footer'></div>

where #header is fixed and may have variable height, #contents should consume all remaining vertical space and #footer is fixed and may have variable height you can do:

/* Note you could add a container div instead of using the body */
body {
  display: flex;
  flex-direction: column;
}
#header {
  flex: none;
}
#contents {
  flex: 1;
  height: 100%;
  overflow-y: scroll;
}
#footer {
  flex: none;
}

Note that this will allow the contents to scroll vertically to show it's whole contents.

You can read more about display:flex here.

owencm
  • 8,384
  • 6
  • 38
  • 54
8

The trick about height:100% is that it requires all of the parent containers to be have their heights set as well. Here's an html example

<html>
  <body>
    <div id="container">
    </div>
  </body>
</html>

in order for the container div with a height set to 100% to expand dynamically to the height of the window you need to make sure that the body and html elements have their heights set to 100% as well. so...

html
{
    height: 100%;
}
body
{
    height: 100%;
}
#container
{
    height: 100%;
}

would give you a container that expands to fit your window. then if you need to have footer or header that floats above this window you can do so with z indexing. This is the only solution I've found that fills the vertical height dynamically.

e.w. parris
  • 1,093
  • 10
  • 11
  • 2
    Yes, but this causes a problem. A page level container will expand below the screen and you will have to scroll a bit, vertically. You could set container height to < 100%. But, is there another way ? – HelloWorldNoMore Apr 26 '16 at 19:30
  • "The trick about height:100% is that it requires all of the parent containers to be have their heights set as well" made it for me – PALEN Jul 06 '17 at 17:33
  • try: "Height: calc(100% - 75px)" or whatever the height of your footer is. – Kaelan Dawnstar Jul 28 '20 at 22:34
7

Try changing your css to this:

html,
body {
  height: 100%;
  background-color: yellow;
}
header {
  width: 100%;
  height: 150px;
  background-color: blue;
}
header nav ul li {
  display: inline;
  padding: 0 30px 0 0;
  float: left;
}
#wrapper {
  min-height: 100%;
  height: auto !important;
  height: 100%;
  margin: 0 0 -30px 0;
  /* the bottom margin is the negative value of the footer's height */
  position: relative;
}
#content {
  background-color: pink;
  width: 400px;
  padding: 25px 30px 25px 30px;
  position: absolute;
  bottom: 30px;
  top: 150px;
  margin-left: 100px;
}
footer {
  margin: -30px 0 0 0;
  width: 100%;
  height: 30px;
  background-color: green;
}
<div id="wrapper">

  <header>
    <div id="logo"></div>

    <nav>
      <ul>
        <li>About</li>
        <li>Menu</li>
        <li>Specials</li>
      </ul>
    </nav>
  </header>

  <div id="content">
    content
    <br>goes
    <br>here
  </div>

</div>

<footer>footer</footer>

You probably don't want to be setting the width, padding, margins, ect. of the wrapper. Also, with absolute positioning you can pull the bottom and top of the content to where you want them.

Here's what you are after, I think.

Ruslan López
  • 4,433
  • 2
  • 26
  • 37
Gabriel Syme
  • 445
  • 4
  • 7
5

I spend several hours trying to figure this out too and finally have a robust solution without hacks. However, it requires CSS3, which requires a modern browser to support it. So, if this constraint works for you, then I have a real solution for you that works.

http://jsfiddle.net/u9xh4z74/ Copy this code into your own file if you need proof, as the JSFiddle will not actually render the flexbox correctly as embedded code.

Basically, you need to - set the target container to 100% height, which you seem to already know - the parent container you set display: flex and flex-direction: vertical (you'll see in the JSFiddle I've also included the alternate styles that do the same thing but are needed for cross browser support) - you can let the header and footer be their natural heights and dont need to specify anything in that regard - in the container you want to fill up the remaining space, set flex: 1. You're set! You'll see it works exactly as you semantically have intended. Also in the JSFiddle, I included overflow: auto to demonstrate that if you have even more text than the screen can handle, scrolling works as you would want it to.

<div style="display:flex; flex-direction:vertical;">
    ...header(s)...
    <div style="flex: 1; overflow: auto;">
         As much content as you want.
    </div>
    ...footer(s)...
</div>

As a side note, I pursued the option of trying to do this same thing using display: table. It works just fine as well, except that overflowed content does not work as you would expect, instead overflowed content simply expands the container to the size of the content, which I'm pretty sure is not what you want. Enjoy!

Stan Lin
  • 928
  • 7
  • 6
1

Use display:table and display:table-row Set height:0 for normal divs and height:auto for div that should fill vertical space. Insert a div with {height:100%; overflow-y:auto} into the vertical filler to if the containers height shouldn't expand beyond its preset height. Behold the power of display:table!

<div style="height:300px;">
  <div style="display:table; height:100%; width:100%;border: 1px solid blue;">
    <div style="display: table-row; height:0; padding:2px; background-color:yellow;">
      Hello          
    </div>
    <div style="display: table-row; height:auto; padding:2px; background-color:green;">
      <div style="height:100%; overflow: auto;">
        <div style="height: 500px"></div>
      </div>
    </div>
    <div style="display: table-row; height:0; padding:2px; background-color:yellow;">
      Gbai
    </div>
  </div>
</div>
clearfix
  • 467
  • 1
  • 5
  • 10
-5

There is no 100% height from 100% continer height exactly. You can't solve it this way. Likewise while using mix of height + margin + padding. This is way straight to hell. I suggest you to take a look for tutorials which are sloving this page layout.

Jirka Kopřiva
  • 2,939
  • 25
  • 28