tags:

views:

229

answers:

6

This is a problem I have encountered several times over the years, and I always give up and use JavaScript to do the calculations on the page resize event. Can it be done with pure CSS?

I need to fashion a CSS layout like this:

+---------------------------
 header  -->
+---------------------------
 menu | scrollable content
      | --->
   |  | |
   v  | v
      |
+---------------------------
footer -->
+---------------------------

A fixed-height header should stick to the top and expand horizontally to meet the rightmost edge of the window. A fixed-height footer should stick to the bottom and also expand horizontally to meet the rightmost edge of the window. A fixed-width menu should stick to the left and expand to meet header and footer. A content area should fill the remaining space. The content area may scroll, but never the page itself.

+1  A: 

This can very easily be done in CSS in all browsers including IE6 IF you don't use tables and only DIVs. Not sure what kind of content you will be displaying though...is it tabular data?

<div class="fixed-header"></div>
<div class="menu-content-group"><div class="menu"><div class="menu-child"></div></div><div class="content"><div class="content-child"></div></div></div>
<div class="fixed-footer"></div>

html, body {
  width:100%;
  height:100%;
}

.fixed-header, .fixed-footer {
 display:block;
 position:absolute;
 width:100%;
 height:50px; /* whatever height you want for your header */
 float:left;
 top:0;
 left:0;
 z-index:2;
}

.fixed-footer {
 top:;
 bottom:0;
}

.menu-content-group {
  display:block;
  position:absolute;
  width:100%;
  height:100%;
  float:left;
  top:0;
  left:0;
}

.menu {
  display:block;
  position:absolute;
  width:100px;
  height:100%;
  top:0;
  left:0;
  z-index:1;
}

.content {
  display:block;
  position:absolute;
  width:100%;
  height:100%;
  top:0;
  left:0;
  overflow-x:hidden;
  overflow-y:auto;
}

.menu-child {
  display:block;
  position:relative;
  width:100px;
  height:auto;
  top:50px;
}

.content-child {
  display:block;
  position:relative;
  width:100%:
  padding:50px 0;
  padding-left:100px;
}

Mark
The content could be anything... This layout will function as a page template that my web app's individual pages then populate.
nw
Well, that's nice that it can be "easily done" but this doesn't really constitute an answer does it?
cletus
Working on an edit with an answer.
Mark
You would of course have to tweak it and play around with some properties like the padding of the content-child...it might work better with margin instead of padding.
Mark
+1  A: 

It's easy using DIVs and position:fixed, if your targeted browsers support it.

See http://www.quirksmode.org/css/contents.html

Do you need to support IE6? (default browser in non-updated WinXP) If not, it's definitely doable.

Emyr
#header{position:fixed;top:0px;width:auto;height:100px;}#footer{position:fixed;bottom:0px;width:auto;height:100px;}#menu{position:fixed;margin:100px 0px; /*avoid head/foot overlap*/left:0px;height:auto;width:250px;}#main{overflow:scroll;top:100px;margin-left:250px;bottom:100px;width:100px;}You'll need to finish off #main ;-)
Emyr
+2  A: 

If you don't need to support IE6, yes.

html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

.Header {
    width: 100%;
    height: 100px;
}
.Menu {
    position: absolute;
    left: 0;
    top: 100px;
    bottom: 50px;
    width: 175px;
}
.Footer {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 50px;
    width: 100%;
}
.Content {
    position: absolute;
    width: auto;
    height: auto;
    left: 175px;
    top: 100px;
    right: 0;
    bottom: 50px;
    overflow: scroll;
}

I didn't actually test this.

SLaks
Absolute means the element position is fixed vs the whole page, not the viewport. You need position:fixed.
Emyr
this won't work because you can't use overflow:scroll on an element that has auto for width/height
Mark
Read more carefully. I'm using `overflow: scroll` on the content, the page page itself won't scroll.
SLaks
@Mark: Are you sure?
SLaks
Thats what I am referring to is the .Content. if you have height and width set to auto that means it will resize .Content to fit the content and it will never actually scroll anything. It needs to have a pre determined height or width for overflow to happen. If you set the CSS width/height to auto you would need javascript to set an actual width/height based on the width/height of the window.
Mark
Still testing, but this seems to work perfectly.
nw
@nw: Just make sure that the overflow works correctly.
SLaks
+1  A: 

See the source of this and this for example. (Or just google for more..)

Nimbuz
A: 

Maybe you could start from this article: How to keep footers at the bottom of the page. Then you would apply the technique to this 'Left Menu' 2 Column Liquid Layout (Percentage widths).

Gregory Pakosz
A: 

If I am understanding this correctly this may work. By setting a div around the actual stuff you need to expand and setting it to display as a table and any parts like the sidebar to display like cells you can get equal cols. Fix the footer and header to the window with fixed and set the z-index high on them. I tested the bottom code in safari, this won't work in ie6 without javascript to calculate heights.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
<html lang="en">
<head>
 <title></title>
 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
 <style type="text/css">
 *{margin:0; padding:0;}
  #header{ height:50px; width:100%; position:fixed; top:0; background:red; z-index:99999;}
    #group{display:table-row; clear:both; width:100%; position:absolute; top:50px; overflow:hidden;}
    #sidebar{display:table-cell; width:200px; background:#e3e; float:left; height:100%; vertical-align:top; position:fixed; top:50px; padding-bottom:150px;}
 #sidebar-inside{padding-bottom:150px; max-height:500px; overflow:hidden;}
    #content{  margin-left:200px;}
 #footer{ height:50px; width:100%; position:fixed; bottom:0; background:red; z-index:99999;}
 </style>

</head>
<body>
 <div id="header"><!-- CONTENT HERE --></div>
    <div id="group"> 
    <div id="sidebar">
  <div id="sidebar-inside"></div>
       </div>
    <div id="content"></div>
    </div>
    <div id="footer"></div>

</body>
Chad