Reputation: 2663
I have an HTML page which is divided into 4 sections.
I am using 1 div for each section and 1 div which wraps all the 4 divs.
My header's height is 50px, the menu's height is 50px, and the footer's height is 20px.
Then I try setting the menu's height to 100%. Menu div is taking the height of its container which is creating scrollbars in my page.
The CSS is as follows:
html, body {
margin: 0px;
height: 100%;
width: 100%;
min-width: 1024px;
min-height: 500px;
}
#container {
width: 100%;
height: 100%;
}
#header {
width: 100%;
height: 50px;
}
#menu {
width: 100%;
height: 50px;
}
#content {
width: 100%;
height: 100%;
}
#footer {
width: 100%;
height: 20px;
}
Is it possible with CSS alone or I have to use JavaScript also?
Upvotes: 2
Views: 3604
Reputation: 14094
Here is another Pure CSS solution, that works without specifying any height whatsoever. [this solution deserves its own answer]
Here's a Working Fiddle
because maybe your header will change one day affecting his height, or your menu will grow, or your footer will need an extra line causing his height to grow..
all of that changes will cause you to re-fix another height for the changing element, and recalculate the right height for the content.
my solution makes it easier, because all the parts are fluid. let them take the space they need in the page, and the content will always take the remaining height.
Tested On: IE10, Firefox, Chrome, Safari, Opera. (not working on older IE, not tested on other browsers)
yes. unfortunately, because of the way that this trick works, you will need to change the arrangement of your HTML.
I found a Pure CSS way to create a div
container, with two child div
's.
the first will take the exact height he needs, and the second will take the remaining of the container height's.
but what if I want the opposite scenario,
What if I want second div
to take his exact space and the first div
to take the container's remaining height?
I didn't find an easy way to do that with Pure CSS.
thats why, I actually reverse the order of the div
s, the first holds the second data, and the second holds the first data, now we let the first div to take his exact height, and the second stretch to the end of the container as we want, and then I rotate their view via CSS to make them appear in order.
For your case it means that you will have to create the HTML in that order.
HTML:
<div class="Container">
<div class="Header">I'm in the header</div>
<div class="Menu">I'm in the menu</div>
<div class="HeightTaker">
<div class="Wrapper Container Inverse">
<div>
<div class="Footer">I'm in the footer</div>
</div>
<div class="HeightTaker">
<div class="Wrapper">
<div class="Content">
I'm in the content
</div>
</div>
</div>
</div>
</div>
</div>
CSS:
*
{
margin: 0;
padding: 0;
}
html, body, .Container
{
height: 100%;
}
.Container:before
{
content: '';
height: 100%;
float: left;
}
.HeightTaker
{
position: relative;
z-index: 1;
}
.HeightTaker:after
{
content: '';
clear: both;
display: block;
}
.Wrapper
{
position: absolute;
width: 100%;
height: 100%;
}
.Inverse, .Inverse > *
{
-moz-transform: rotateX(180deg);
-ms-transform: rotateX(180deg);
-o-transform: rotate(180deg);
-webkit-transform: rotateX(180deg);
transform: rotateX(180deg);
}
.Header
{
/*for demonstration only*/
background-color: #bf5b5b;
}
.Menu
{
/*for demonstration only*/
background-color: #6ea364;
}
.Content
{
height: 100%;
overflow: auto;
/*for demonstration only*/
background-color: #90adc1;
}
.Footer
{
/*for demonstration only*/
background-color: #b5a8b7;
}
Upvotes: 3
Reputation: 14094
using calc()
(CSS3)
HTML:
<div id="container">
<div id="header">header</div>
<div id="menu">menu</div>
<div id="content">content</div>
<div id="footer">footer</div>
</div>
CSS:
html, body {
margin: 0px;
height: 100%;
/*min-width: 1024px;
min-height: 500px;*/ /*You can uncomment that back if you want)*/
}
#container {
height: 100%;
}
#header {
height: 50px;
}
#menu {
height: 50px;
}
#content {
height: calc(100% - 120px); /*120 = 50 + 50 + 20*/
overflow: auto;
}
#footer {
height: 20px;
}
notice I removed your width:100%
because this is the default behavior of a block element like a div.
This can also be done without stating any height at all, with Pure CSS. Check my second answer in that page.
Upvotes: 2
Reputation: 78590
Here's a thought. May not work for your specific problem, but it does address the issue of mixing pixels and percents. Under the current definition of the problem, you use a fixed height for both the top (header, menu) and bottom (footer). But you want to have the content take up the rest. One solution would be to pad the top and bottom of the container with the same height of the header and menu on top and the same height as the footer on the bottom. The problem then is that you have a 100% height container plus 100px on top and 20px on bottom. But there's a CSS convention for that. It's called box-sizing and is very cross browser compatible (as long as you include -moz). in effect, it calculates 100% height after including the padding. Therefore, 100% height plus all the padding still equals 100% height.
In practice it looks like this
<div class="container">
<div class="header"></div>
<div class="menu"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
html, body, .container {
min-height: 100%;
background:#eee;
}
.header {
height: 50px;
position: relative;
z-index: 1;
}
.menu {
height: 50px;
position: relative;
z-index: 1;
}
.footer {
height: 20px;
width: 100%; /* needed because this one is position absolute */
bottom: 0%;
position:absolute;
}
.content {
height: 100%;
width: 100%; /* needed because this one is position absolute */
top: 0%;
left: 0%;
padding-top: 100px;
padding-bottom: 20px;
position:absolute;
box-sizing: border-box; /* here's the kicker */
-moz-box-sizing: border-box;
overflow: auto; /* don't panic. they take the place of normal scroll bars*/
}
http://jsfiddle.net/WLR5S/show
http://jsfiddle.net/WLR5S/6/show (with -moz for firefox)
Obviously, the point is that you can have 100% height elements with padding to compensate for footer and header
You have to use position absolute for the content and footer, and you have to apply position relative with z-index to the header area
After a little more experimenting, I found that it's probably best to use height instead of min-height and apply overflow:auto
or the like. That way the page has appropriate sidebars if the content gets to be too large: http://jsfiddle.net/WLR5S/2/ or http://jsfiddle.net/WLR5S/3/
Upvotes: 2