From my research, this appears to be an absolutely classic CSS question, but I can't find a definitive answer - so StackOverflow it is.
How do I set a content div to take up 100% of the body height, minus the height taken up by a fixed-height header and footer?
<body>
<header>title etc</header>
<div id="content">body content</div>
<footer>copyright etc</footer>
</body>
//CSS
html, body {
height: 100%;
}
header {
height: 50px;
}
footer {
height: 50px;
}
#content {
height: 100% of the body height, minus header & footer
}
I would like to use pure CSS, and for the answer to be bulletproof across browsers.
This question is related to
css
You can take advatange of the css property Box Sizing.
#content {
height: 100%;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
padding-top: 50px;
margin-top: -50px;
padding-bottom: 50px;
margin-bottom: -50px;
}
See the JsFiddle.
This question has been pretty well answered, but I'm taking the liberty of adding a javascript solution. Just give the element that you want to 'expand' the id footerspacerdiv
, and this javascript snippet will expand that div until the page takes up the full height of the browser window.
It works based on the observation that, when a page is less than the full height of the browser window, document.body.scrollHeight is equal to document.body.clientHeight. The while loop increases the height of footerspacerdiv
until document.body.scrollHeight is greater than document.body.clientHeight. At this point, footerspacerdiv
will actually be 1 pixel too tall, and the browser will show a vertical scroll bar. So, the last line of the script reduces the height of footerspacerdiv
by one pixel to make the page height exactly the height of the browser window.
By placing footerspacerdiv
just above the 'footer' of the page, this script can be used to 'push the footer down' to the bottom of the page, so that on short pages, the footer is flush with the bottom of the browser window.
<script>
//expand footerspacer div so that footer goes to bottom of page on short pages
var objSpacerDiv=document.getElementById('footerspacer');
var bresize=0;
while(document.body.scrollHeight<=document.body.clientHeight) {
objSpacerDiv.style.height=(objSpacerDiv.clientHeight+1)+"px";
bresize=1;
}
if(bresize) { objSpacerDiv.style.height=(objSpacerDiv.clientHeight-1)+"px"; }
</script>
As far as it is not cross browser solution, you might be take advantage of using calc(expression)
to achive that.
html, body {
height: 100%;
}
header {
height: 50px;
background-color: tomato
}
#content {
height: -moz-calc(100% - 100px); /* Firefox */
height: -webkit-calc(100% - 100px); /* Chrome, Safari */
height: calc(100% - 100px); /* IE9+ and future browsers */
background-color: yellow
}
footer {
height: 50px;
background-color: grey;
}
If you want to know more about calc(expression)
you'd better to visit this site.
This still came up as the top Google result when I was trying to find an answer to this question. I didn't have to support older browsers in my project and I feel like I found a better, simpler solution in flex-box. The CSS snippet below is all that is necessary.
I have also shown how to make the main content scrollable if the screen height is too small.
html,_x000D_
body {_x000D_
height: 100%;_x000D_
display: flex;_x000D_
flex-direction: column;_x000D_
}_x000D_
header {_x000D_
min-height: 60px;_x000D_
}_x000D_
main {_x000D_
flex-grow: 1;_x000D_
overflow: auto;_x000D_
}_x000D_
footer {_x000D_
min-height: 30px;_x000D_
}
_x000D_
<body style="margin: 0px; font-family: Helvetica; font-size: 18px;">_x000D_
<header style="background-color: lightsteelblue; padding: 2px;">Hello</header>_x000D_
<main style="overflow: auto; background-color: lightgrey; padding: 2px;">_x000D_
<article style="height: 400px;">_x000D_
Goodbye_x000D_
</article>_x000D_
</main>_x000D_
<footer style="background-color: lightsteelblue; padding: 2px;">I don't know why you say, "Goodbye"; I say, "Hello."</footer>_x000D_
</body>
_x000D_
Here's a solution that doesn't use negative margins or calc
. Run the snippet below to see the final result.
Explanation
We give the header and the footer a fixed height of 30px
and position them absolutely at the top and bottom, respectively. To prevent the content from falling underneath, we use two classes: below-header
and above-footer
to pad the div above and below with 30px
.
All of the content is wrapped in a position: relative
div so that the header and footer are at the top/bottom of the content and not the window.
We use the classes fit-to-parent
and min-fit-to-parent
to make the content fill out the page. This gives us a sticky footer which is at least as low as the window, but hidden if the content is longer than the window.
Inside the header and footer, we use the display: table
and display: table-cell
styles to give the header and footer some vertical padding without disrupting the shrink-wrap quality of the page. (Giving them real padding can cause the total height of the page to be more than 100%
, which causes a scroll bar to appear when it isn't really needed.)
.fit-parent {_x000D_
height: 100%;_x000D_
margin: 0;_x000D_
padding: 0;_x000D_
}_x000D_
.min-fit-parent {_x000D_
min-height: 100%;_x000D_
margin: 0;_x000D_
padding: 0;_x000D_
}_x000D_
.below-header {_x000D_
padding-top: 30px;_x000D_
}_x000D_
.above-footer {_x000D_
padding-bottom: 30px;_x000D_
}_x000D_
.header {_x000D_
position: absolute;_x000D_
top: 0;_x000D_
height: 30px;_x000D_
width: 100%;_x000D_
}_x000D_
.footer {_x000D_
position: absolute;_x000D_
bottom: 0;_x000D_
height: 30px;_x000D_
width: 100%;_x000D_
}_x000D_
_x000D_
/* helper classes */_x000D_
_x000D_
.padding-lr-small {_x000D_
padding: 0 5px;_x000D_
}_x000D_
.relative {_x000D_
position: relative;_x000D_
}_x000D_
.auto-scroll {_x000D_
overflow: auto;_x000D_
}_x000D_
/* these two classes work together to create vertical centering */_x000D_
.valign-outer {_x000D_
display: table;_x000D_
}_x000D_
.valign-inner {_x000D_
display: table-cell;_x000D_
vertical-align: middle;_x000D_
}
_x000D_
<html class='fit-parent'>_x000D_
<body class='fit-parent'>_x000D_
<div class='min-fit-parent auto-scroll relative' style='background-color: lightblue'>_x000D_
<div class='header valign-outer' style='background-color: black; color: white;'>_x000D_
<div class='valign-inner padding-lr-small'>_x000D_
My webpage_x000D_
</div>_x000D_
</div>_x000D_
<div class='fit-parent above-footer below-header'>_x000D_
<div class='fit-parent' id='main-inner'>_x000D_
Lorem ipsum doloris finding dory Lorem ipsum doloris finding_x000D_
dory Lorem ipsum doloris finding dory Lorem ipsum doloris_x000D_
finding dory Lorem ipsum doloris finding dory Lorem ipsum_x000D_
doloris finding dory Lorem ipsum doloris finding dory Lorem_x000D_
ipsum doloris finding dory Lorem ipsum doloris finding dory_x000D_
Lorem ipsum doloris finding dory Lorem ipsum doloris finding_x000D_
dory Lorem ipsum doloris finding dory Lorem ipsum doloris_x000D_
finding dory Lorem ipsum doloris finding dory Lorem ipsum_x000D_
doloris finding dory Lorem ipsum doloris finding dory Lorem_x000D_
ipsum doloris finding dory Lorem ipsum doloris finding dory_x000D_
Lorem ipsum doloris finding dory Lorem ipsum doloris finding_x000D_
dory Lorem ipsum doloris finding dory Lorem ipsum doloris_x000D_
finding dory Lorem ipsum doloris finding dory Lorem ipsum_x000D_
doloris finding dory Lorem ipsum doloris finding dory Lorem_x000D_
ipsum doloris finding dory Lorem ipsum doloris finding dory_x000D_
Lorem ipsum doloris finding dory Lorem ipsum doloris finding_x000D_
dory Lorem ipsum doloris finding dory Lorem ipsum doloris_x000D_
finding dory Lorem ipsum doloris finding dory Lorem ipsum_x000D_
doloris finding dory Lorem ipsum doloris finding dory Lorem_x000D_
ipsum doloris finding dory Lorem ipsum doloris finding dory_x000D_
Lorem ipsum doloris finding dory Lorem ipsum doloris finding_x000D_
dory Lorem ipsum doloris finding dory Lorem ipsum doloris_x000D_
finding dory Lorem ipsum doloris finding dory Lorem ipsum_x000D_
doloris finding dory Lorem ipsum doloris finding dory Lorem_x000D_
ipsum doloris finding dory Lorem ipsum doloris finding dory_x000D_
Lorem ipsum doloris finding dory Lorem ipsum doloris finding_x000D_
dory Lorem ipsum doloris finding dory Lorem ipsum doloris_x000D_
finding dory Lorem ipsum doloris finding dory Lorem ipsum_x000D_
doloris finding dory Lorem ipsum doloris finding dory Lorem_x000D_
ipsum doloris finding dory Lorem ipsum doloris finding dory_x000D_
Lorem ipsum doloris finding dory Lorem ipsum doloris finding_x000D_
dory Lorem ipsum doloris finding dory Lorem ipsum doloris_x000D_
finding dory Lorem ipsum doloris finding dory Lorem ipsum_x000D_
doloris finding dory Lorem ipsum doloris finding dory Lorem_x000D_
ipsum doloris finding dory Lorem ipsum doloris finding dory_x000D_
</div>_x000D_
</div>_x000D_
<div class='footer valign-outer' style='background-color: white'>_x000D_
<div class='valign-inner padding-lr-small'>_x000D_
© 2005 Old Web Design_x000D_
</div>_x000D_
</div>_x000D_
</div>_x000D_
</body>_x000D_
</html>
_x000D_
The new, modern way to do this is to calculate the vertical height by subtracting the height of both the header and the footer from the vertical-height of the viewport.
//CSS
header {
height: 50px;
}
footer {
height: 50px;
}
#content {
height: calc(100vh - 50px - 50px);
}
Trying to calculate the header and footer is bad :( A design should be simple, self explanatory. Plain easy. Calculations are just...not easy. Not easy for human and a bit hard on machines.
What you're looking for is a subset of the Holy Grail design.
Here's an implementation using the flex display. It includes side bars in addition to the footer and header. Enjoy:
<!DOCTYPE html>
<html style="height: 100%">
<head>
<meta charset=utf-8 />
<title>Holy Grail</title>
<!-- Reset browser defaults -->
<link rel="stylesheet" href="reset.css">
</head>
<body style="display: flex; height: 100%; flex-direction: column">
<div>HEADER<br/>------------
</div>
<!-- No need for 'flex-direction: row' because it's the default value -->
<div style="display: flex; flex: 1">
<div>NAV|</div>
<div style="flex: 1; overflow: auto">
CONTENT - START<br/>
<script>
for (var i=0 ; i<1000 ; ++i) {
document.write(" Very long content!");
}
</script>
<br/>CONTENT - END
</div>
<div>|SIDE</div>
</div>
<div>------------<br/>FOOTER</div>
</body>
</html>
Source: Stackoverflow.com