Get div to take up 100% body height, minus fixed-height header and footer [duplicate]
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.
Solution 1:
this version will work in all the latest browsers and ie8 if you have the modernizr script (if not just change header
and footer
into div
s):
Fiddle
html,
body {
min-height: 100%;
padding: 0;
margin: 0;
}
#wrapper {
padding: 50px 0;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
#content {
min-height: 100%;
background-color: green;
}
header {
margin-top: -50px;
height: 50px;
background-color: red;
}
footer {
margin-bottom: -50px;
height: 50px;
background-color: red;
}
p {
margin: 0;
padding: 0 0 1em 0;
}
<div id="wrapper">
<header>dfs</header>
<div id="content">
</div>
<footer>sdf</footer>
</div>
Scrolling with content: Fiddle
Solution 2:
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;
}
Example at JsFiddle
If you want to know more about calc(expression)
you'd better to visit this site.
Solution 3:
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,
body {
height: 100%;
display: flex;
flex-direction: column;
}
header {
min-height: 60px;
}
main {
flex-grow: 1;
overflow: auto;
}
footer {
min-height: 30px;
}
<body style="margin: 0px; font-family: Helvetica; font-size: 18px;">
<header style="background-color: lightsteelblue; padding: 2px;">Hello</header>
<main style="overflow: auto; background-color: lightgrey; padding: 2px;">
<article style="height: 400px;">
Goodbye
</article>
</main>
<footer style="background-color: lightsteelblue; padding: 2px;">I don't know why you say, "Goodbye"; I say, "Hello."</footer>
</body>
Solution 4:
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);
}
Solution 5:
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>