Sticky header and footer scrollable 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.
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.
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
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.
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/[email protected]/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>