16

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.

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 container 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.

Stickers
  • 75,527
  • 23
  • 147
  • 186
Michael
  • 9,060
  • 14
  • 61
  • 123
  • you need to specify a height setting on the div with the overflow – Liquidchrome Jun 17 '16 at 18:00
  • @Liquidchrome I don't know what the height is... whatever it takes to display the content. – Michael Jun 17 '16 at 18:02
  • Well... you could go by the percentage of the height of the main container and set percentages for each div within to set the heights, but that would make the header footer different pixel size depending on the user's screen. https://jsfiddle.net/tdxn1e7p/2/ – Liquidchrome Jun 17 '16 at 18:11
  • Does this answer your question? [Fixed header, footer with scrollable content](https://stackoverflow.com/questions/4069734/fixed-header-footer-with-scrollable-content) – Drew Reese Apr 06 '23 at 22:46

4 Answers4

42

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;
}
.header, .footer {
  background: silver;
}
.content {
  flex: 1;
  overflow: auto;
  background: pink;
}
<div class="wrapper">
  <div class="header">Header</div>
  <div class="content">
    <div style="height:1000px;">Content</div>
  </div>
  <div class="footer">Footer</div>
</div>

Approach 2 - CSS table

For both known and unknown height elements. It also works in legacy browsers including IE8.

jsFiddle

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

Approach 3 - calc()

If header and footer are fixed height, you can use CSS calc().

jsFiddle

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

html, body {
  height: 100%;
  margin: 0;
}
.wrapper {
  height: 100%;
}
.header, .footer {
  height: 10%;
  background: silver;
}
.content {
  height: 80%;
  overflow: auto;
  background: pink;
}
<div class="wrapper">
  <div class="header">Header</div>
  <div class="content">
    <div style="height:1000px;">Content</div>
  </div>
  <div class="footer">Footer</div>
</div>

jsFiddle

Stickers
  • 75,527
  • 23
  • 147
  • 186
  • Flexbox approach works great. I used the body tag as the wrapper; a straight forward and responsive approach...really cool thx! – Mark Dalsaso Jun 27 '19 at 19:10
6

In Bootstrap 4.0, to have a fixed header and footer with scrolling content, wrap everything .container-fluid, as you likely are. Use .fixed-top and fixed-bottom class in your header and footer divs. Of course, you have to have enough content (overflow) so you can see it scrolling.

Jack Mason
  • 141
  • 2
  • 3
1

The flexbox approach by @Sticker worked nicely. For those on Bootstrap 4, you can avoid the custom CSS:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" rel="stylesheet"/>

<html class="h-100">
  <body class="h-100">
    <div class="wrapper d-flex flex-column h-100">
      <div class="header">Header</div>
      <div class="content flex-grow-1 overflow-auto">
        <div style="height:1000px;">Content</div>
      </div>
      <div class="footer">Footer</div>
    </div>
  </body>
</html>
Philipp
  • 891
  • 1
  • 11
  • 12
0

overflow: auto applies to the content inside the element. But the div currently has a fluid height, so its content never overflows it.

If you want the content div to scroll rather than overflow the page, you need to add a maximum height to it, like

<div style="max-height: 80%;">

This will make the div take up to 80% of the height of the page, but never more than that. Then you should probably also set the body to overflow: hidden to deal with the margins: Updated demo.

rvighne
  • 20,755
  • 11
  • 51
  • 73