Michael Michael - 5 months ago 22
CSS Question

Sticky header and footer scrollable middle content

I'm trying to create a page which contains three divs: a header, a footer, and a content area. These should take up 100% of the screen and not scroll.

The header and footer are small and won't change, the content area could be any size, so I have added

overflow:auto
to make it scroll when it gets too large.

The problem is, it overflows the height of the screen. I have created a fiddle to demonstrate:
https://jsfiddle.net/tdxn1e7p/

I'm using the following CSS to set up the html and body height so the
height:100%
trick on the main content will work:

html,
body {
height: 100%;
}


The structure of my document is:

<div style="height:100%">
<div>
Header content
</div>
<div style="overflow:auto;">
Body content... this could be very long
</div>
<div>
Footer content
</div>
</div>


I have found a lot of variations on this sort of problem such as this question, but haven't been able to make any of the answers work for me.

Answer

Approach 1 - flexbox

It works great for both known and unknown height elements. Make sure to set the outer div to height: 100%; and reset the default margin on body. See the browser support tables.

jsFiddle

html, body {
  height: 100%;
  margin: 0;
}
.wrapper {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.content {
  background: pink;
  flex: 1;
  overflow: auto;
}
<div class="wrapper">
  <div class="header">
    Header example
  </div>
  <div class="content">
    <div style="height:1000px;">Content example (1000px height)</div>
  </div>
  <div class="footer">
    Footer example
  </div>
</div>

Approach 2 - CSS table

For both known and unknown height elements. It also works in legacy browsers even in IE8, see the support tables. Note, some additional markup is needed.

jsFiddle

html, body {
  height: 100%;
  margin: 0;
}
.wrapper {
  height: 100%;
  width: 100%;
  display: table;
}
.header, .content, .footer {
  display: table-row;
}
.inner {
  display: table-cell;
}
.content .inner {
  background: pink;
  height: 100%;
  position: relative;
}
.scrollable {
  position: absolute;
  left: 0; right: 0;
  top: 0; bottom: 0;
  overflow: auto;
}
<div class="wrapper">
  <div class="header">
    <div class="inner">
      Header example
    </div>
  </div>
  <div class="content">
    <div class="inner">
      <div class="scrollable">
        <div style="height:1000px;">Content example (1000px height)</div>
      </div>
    </div>
  </div>
  <div class="footer">
    <div class="inner">
      Footer example
    </div>
  </div>
</div>

Approach 3 - calc()

If they are fixed height with px or em etc, you can use CSS calc().

jsFiddle

html, body {
  height: 100%;
  margin: 0;
}
.wrapper {
  height: 100%;
}
.header, .footer {
  height: 50px;
}
.content {
  height: calc(100% - 100px);
  background: pink;
  overflow: auto;
}
<div class="wrapper">
  <div class="header">
    Header example
  </div>
  <div class="content">
    <div style="height:1000px;">Content example (1000px height)</div>
  </div>
  <div class="footer">
    Footer example
  </div>
</div>

Approach 4 - % for all

If the header and footer are known height, and they are also percentage you can just do the simple math making them together of 100% height.