CSS fluid height?

JavaScript and client side scripting.

Moderator: General Moderators

alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

CSS fluid height?

Post by alex.barylski »

Assume I have some markup such as:

Code: Select all

<div style="height: 100%; background-color: orange">
  <div style="height: 80px; background-color: red">
    Some header text
  </div>
  <div style="height: 50%; background-color: green">
    Some body text

    This DIV needs to fill all the height not just 50%???
  </div>
</div>
How can this be achieved?

I have tried reducing the bottom DIV margin-height: -80px but this has no effect???

Thankfully my design can use percetages, but as a learning excersize I would like to know how to do this in the future as most of my designs have fixed header heights???

Cheers :)
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

You want to have a div that fills the entire window, that holds one div that fills 80px of the div, and a div below that that fills the rest?

Code: Select all

<style type="text/css">
html, body{height: 100%; width: 100%;}
</style>
<div style="height: 100%; background-color: orange">
  <div style="float: left; width: 100%; height: 80px; background-color: red">
    Some header text
  </div>
  <div style="clear: left; height: 100%; background-color: green">
    Some body text<br />

    This DIV needs to fill all the height not just 50%???
  </div>
</div>  
I think. Tell me if it works.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

hehe...not quite:

Code: Select all

  <div style="height: 10%; background-color: red"> 
    <h1>CompanyName</h1>
  </div> 
  <div style="height: 90%; background-color: green"> 
    Main content area
  </div> 
Is essentially what I am trying to accomplish, which works fine, but *typically* my designs have a *fixed* header (somewhere around 80px in height)

The RED DIV is 80px in height and the green should take up whatever is left of it's parent (wraping) DIV height.

If you change the above, to match my criteria, you get:

Code: Select all

  <div style="height: 80px; background-color: red"> 
    <h1>CompanyName</h1>
  </div> 
  <div style="height: 100%; background-color: green"> 
    Main content area
  </div> 
But you will, that the GREEN DIV does *more* than take up remaining space of it's parent, and instead it assumes the entire height of it's parent - including the space the header adds (which is 80px).

Because the height (when calculated at 100%) assume the entire height of it's parent it forces scrollbars to appear because now the GREEN DIV is larger than the visible screen area.

I have tried margin-bottom: -80px but this does not seem to work???
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

I've been tinkering with the following CSS/Markup...

I think if I could get this working, then maybe I would be able to continue with previous message:

Code: Select all

<html>
  <head>
    <style>
      body, html {
        margin: 0px;
        padding: 0px;
      }
    </style>
  </head>
<body>

  <div style="height: 100%; background-color: green">

    <div style="height: 100%; background-color: purple">
      <!-- START -->

      <div style="height: 80px; background-color: red"><!-- Set width to 100% -->
        Web Page Logo
      </div>

      <div style="position: absolute; top: 0px; width: 50%; height: 100%; background-color: orange">
        This is the body content where columns exist!
      </div>

      <!-- FINISH -->
    </div>
  </div>

</body>
</html>
I need the RED header to overlap the orange body area...and the content from the body area to simple shift down using margin-top or padding-top or even top, but it seems FF doesn't like any as it still pushes the bottom down...causing scroll bars to appear...

&@^&%^*% :P

Tables would work flawlessy :)

z-index doesn't work either...

Any ideas?
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

Well I was in school when I answered you earlier, but now I have access to my FTP. Here's how I do it:

Code: Select all

html, body{height: 100%; width: 100%;}
#header{float: left; height: 80px;}
#content{clear: left;}

Code: Select all

<html><body>
<div id="container"><div id="header"></div><div id="content"></div></div>
</body></html>
And that should do it.
nickvd
DevNet Resident
Posts: 1027
Joined: Thu Mar 10, 2005 5:27 pm
Location: Southern Ontario
Contact:

Post by nickvd »

Relative heights have always been a royal PITA in css. The best way I've seen to accomplish the task would be to absolutely position the header at the top of the window, and have a top padding equal to the height of the header.

Give me a few minutes and I'll see what I can come up with...
nickvd
DevNet Resident
Posts: 1027
Joined: Thu Mar 10, 2005 5:27 pm
Location: Southern Ontario
Contact:

Post by nickvd »

superdezign wrote:Well I was in school when I answered you earlier, but now I have access to my FTP. Here's how I do it:

Code: Select all

html, body{height: 100%; width: 100%;}
#header{float: left; height: 80px;}
#content{clear: left;}

Code: Select all

<html><body>
<div id="container"><div id="header"></div><div id="content"></div></div>
</body></html>
And that should do it.
#content needs to stretch to the bottom of the screen...
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

And if there is enough content, it should. If not, why extend it? What about footers? They start at the end of content, not the end of window height.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

Ahh...I'm having a helluva time explaining what it is I'm trying to do...

Code: Select all

<html>
  <head>
    <style>
      body, html {
        margin: 0px;
        padding: 0px;
      }

      .header {
        position: relative;

        z-index: 10;

        height: 80px;
        background-color: red;
      }

      .body {
        position: absolute;
        z-index: 0;
        top: 0px;
        width: 90%;

        height: 100%;
        padding-top: 80px;
        margin-bottom: 80px; /* Hoping to fix FF troubles? :( */

        background-color: orange;
      }
    </style>
  </head>
<body>

  <div style="height: 100%; background-color: green">

    <div style="height: 100%; background-color: purple">
      <!-- START -->

      <div class="header">
        Web Page Logo
      </div>

      <div class="body">
        This is the body
      </div>

      <!-- FINISH -->
    </div>
  </div>

</body>
</html>
Run this code in IE - should work exactly as expected, look at it in FireFox, see the scrollbars? Scroll down you will see - this is no good as it destroys the design.

The red is the header which contains several LI items

The orange DIV will eventually be set to width 100% so ignore the purple - that is simply an artifact I haven't yet removed.

I have tried margin-bottom: 80px but still is not recognized in FireFox...again perfect in IE...

The idea is to mock a design like above (assuming orange is width 100%) so it works in both IE and FF...

Any ideas?
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

Are you sure you understand what height: 100% does?

It extends the height to be exactly the same as it's parent.

100% height on html and body enable other objects to have the exact same height as the window.

Using positioning doesn't decrease the height, it only moves the element with that height.
nickvd
DevNet Resident
Posts: 1027
Joined: Thu Mar 10, 2005 5:27 pm
Location: Southern Ontario
Contact:

Post by nickvd »

I don't have access to ie... care to post a screen capture?

As you said, I don't think we're all on the same page, but I had a go anyway :D

I came across this page and from it, was able to come up with:

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>blah</title>
<style type="text/css">
body {
  margin:0;
  border:0;
  padding:0;
  height:100%; 
  max-height:100%; 
}

#header {
   position:absolute;  
   top:0; left:0; 
   width:100%; 
   height:80px; 
   background:red;
}
#content {
   position:absolute;
   width:100%;
   top:80px; bottom:0; 
   background:green;
}
</style>
</head>
<body>

<div id="header">
Here is the header
</div>

<div id="content">
Here is the Main Content
</div>

</body>
</html>
Keep in mind that I don't have IE on this machine (Ubuntu).

Your other option would be to fall back to tables, but only use one main table to cement the overall layout, and use css to style everything else... When time (or money) is a factor (and for some clients it is), a table can be 10 times quicker to set up for the more complex layout requirements.
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

Absolute positioning is a no-no unless it's within a relatively positioned element, fyi.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

superdezign wrote:Absolute positioning is a no-no unless it's within a relatively positioned element, fyi.
Thanks nickvd, I'll paste it and try right away...

superdezign...when and how do you make it absolute to a relative (normal?) element?

BTW- I just found an interesting article here: http://www.alistapart.com/stories/journey/

I had no idea the standards way of calculating width/height was to "include" padding, border, margins, etc...

I think that might have something to do with my margin-bottom: 80px not working as expected in FireFox???

Edit: nickvd works like a charm in FireFox but not in IE - I wonder if I can somehow integrate both so I get something for both...
Last edited by alex.barylski on Fri Feb 16, 2007 10:19 pm, edited 1 time in total.
User avatar
superdezign
DevNet Master
Posts: 4135
Joined: Sat Jan 20, 2007 11:06 pm

Post by superdezign »

You make an element and assign it position: relative, and then anything within it that's set position: absolute; has its top and left defaulted at the top and left of it's parent. But this situation isn't nearly as complicated as you're making it.

The solution I gave you is the one I'm currently using. A 3 column layout with a fixed height header and a fixed height footer. It works fine.

Maybe you want height: auto?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

I'll try and describe what I am doing.

Here are the requirements:

1) Fixed height header (80px)
2) Variable height content area - must assume the *remaining* width of it's parent at a minimum (default is to assume it's parent height which won't work)


Once I have the fixed header & variable content area and optionally fixed or variable height footer I have a standard layout which would make itself handy for most layouts I design. The width is usually fixed at 640 pixels.

Man it would be handy if there was a CSS repository which had nothing but the wire frame output of CSS layouts, so I could click an icon for a three row design and download that CSS template and fill in the area

Anyways, the content (or middle row if you can imagine) has to fill up the *remaining* space whilst accounting for the header (80px or whatever) as well as the footer (80px or whatever). If the page is blank (which is sometimes what happens) the footer would need to be aligned with the bottom of the visible screen area. ONLY if there is more content than can be visisbly seen on screen should scrollbars appear and suggest otherwise.

When you simply set the height to 100% on the middle DIV it takes on the *entire* height of it's parent element. Because the parent is set to 100% it assumes all visible space (AWESOME!) but when you add DIV's it uses those in it's calculation, so...

header = 80px
content = 100% = 480px - assume small resolution
footer = 80px

480 + 80 + 80 = 640px

And because the parent element assumes entire view space at 480 pixels, and 640 is greater than 480, scrollbars appear and the footer gets pushed out of view area, requiring scrolling...

Even though the content area is empty, because it's height is 100% which again, it assumes it's parent so 480px, do the math above and you will see why the scrollbars appear.

*** This is an undesired effect and thows off my designs ***

I can live without footers...but a header is absolutely nessecary and sometimes they aren't based on percentages, but instead pixels (80)...

So I have a header which is 80 pixels and a content area which is height: 100% (480 pixels) I have been struggling to find a method of showing a fixed height header and a variable content area.

The last example given to me does this nicely but only in FireFox!!!

If you know a way to have a fixed header/footer and variable content area which is cross browser, please, I'm very interested in knowing how it's done...I'm dying here :P

Hopefully this clears it up for you - certainly it's help me better understand what it is I am trying to solve... :) which hopefully helps

Cheers :)
Post Reply