CSS Height: Fill available space. No fixed heights
So i have the following structure
<div id="container">
<div id="head"></div>
<div id="body"></div>
<div id="foot"></div>
</div>
I am only using the ids for illustration purposes so this is not even necessarily for a full page.
I want my container to specify a fixed size... or a relative size, does not matter. Lets for argument sake say 300px height. Also overflow: hidden
I want head/foot to expand to fit the content within itself, so height: auto
is sufficient.
I want the body to expand to fit the remaining space in between head and foot. If the content is too big, th开发者_开发百科en scroll (overflow: auto
).
height: 100%
on #body
does not work because then it gains the height of 300px like the parent and pushes part of itself and the footer out of the parent.
Having head and foot position: absolute
does not work because by taking them out of the document flow, some content of #body
is hidden. To fix that we can use padding-top/bottom but we can't set a padding-top: xxpx
/padding-bottom: xxpx
on the #body
because we don't know the necessary height of the head/foot hence why they are height: auto
.
Edit:
I tried converting the container/head/body/foot into a table where the #body
is height: 100%
. This works great except that #body
won't scroll if the content gets too big, instead the entire table expands to show all content. This is not the desired behavior as I need #body
to scroll, not #content
or it's parent.
Any suggestions?
The only solution that immediately comes to mind is display:table-cell, though you run into the problem of lack of support in ie6 & ie7. Perhaps providing the rule for good browsers, and some javascript to calculate differences in height for ie?
Edit:
Here's another approach - using jQuery to calculate the offset. Bear in mind this is just a quick & dirty attempt - it would need to be browser tested and you'd want some simple error handling etc., but it could be a starting point.
Not sure if javascript is the way you want to go but I can't see it being done in pure css.
I changed the ids to classes so that you can have multiple 'fixedHeight' boxes:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'></script>
<script>
$(function() {
$(".fixedHeight").each(function() {
var head = $(this).find(".head");
var body = $(this).find(".body");
var foot = $(this).find(".foot");
body.css("margin-top", head.height()).css("margin-bottom", foot.height());
});
});
</script>
<style>
.head {
background-color: red;
position: absolute;
top: 0;
width:100%;
}
.body {
background-color: blue;
color: white;
overflow: auto;
position:absolute;
top:0;
bottom:0;
width:100%;
margin:2.5em 0;
}
.foot {
background-color: green;
position: absolute;
bottom: 0;
width:100%;
}
.container {
background-color: #aaa;
border: 10px solid orange;
height: 300px;
width: 30%;
position: absolute;
}
</style>
</head>
<body>
<div class="container fixedHeight">
<div class="head">
<h1>Header Content</h1>
</div>
<div class="body">
<p>Body Content</p>
<p>Body Content</p>
<p>Body Content</p>
<p>Body Content</p>
<p>Body Content</p>
<p>Body Content</p>
</div>
<div class="foot">
<p>Footer Content</p>
</div>
</div>
</body>
</html>
Ok so heres a bit of research I got through to sort-of get this working.
#head {
background-color: red;
width: 100%;
position: absolute;
top: 0;
left: 0;
}
#body {
background-color: blue;
color: white;
border: 0 none;
overflow: auto;
height: 100%;
padding-top: 2.5em;
padding-bottom: 2.5em;
box-sizing: border-box;
webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
#foot {
background-color: green;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
}
#container {
background-color: #aaa;
border: 10px solid orange;
height: 300px;
width: 30%;
overflow: show;
position: absolute;
}
This assumes I can calculate the sizes of #head
and #foot
and set the total size to the padding of the appropriate location of #body
. This will push the content of body out of the area which #head/#foot occupy due to their absolute positioning. The problem here is that the scroll bar winds up being cut off partially on the top/bottom because only the content is shifted, the scroll bar is not.
For width, this is not really an issue.
I recently ran into this issue in a situation where I also did not know the total height of the container (like Dmitriy's answer assumes). Let's say the height of #head
and #foot
are 50 and 25 respectively. Here's how I solved it:
#body {
top: 25px;
bottom: 50px;
position: absolute;
}
#foot {
position: absolute;
bottom: 0;
}
精彩评论