Recently I come up with one interesting layout, which proved quite useful. I needed to simulate good old frames, but using CSS over semantic markup. Basic goals:
- liquid layout
- totally centered (both ways) on the page, with possibility of custom margin
- possibility to add static footer
- no limit on scrollable columns/rows
I looked at excellent resources about CSS frames and centered and/or fixed positioning, all available on the net, but none really suited my needs. Either lacking or way too complicated. So, here is mine – centered framed layout.
I tested it and it works in NN7.1, Firefox 0.9, Camino 0.8, WinIE 5.01+, Opera 7.51, Safari 1.2. I tested it and it fails in IE5/Mac (horribly) and Opera 6 (less horrible). Both can be circumvented, but I don’t need that. So, let me indulge myself and explain how it works…
Modern browsers
My layout needed two columns – left would be scrollable (#content), and right would be navigation, fixed (#nav). Those columns are both enclosed by parent div (#horizon) which will define the “frameset” size. Footer is the last piece.
<div id="horizon"> <div id="content"> ... </div><!-- content --> <div id="nav"> ... </div><!-- nav --> </div><!-- horizon --> <p id="footer">© APLUS, 2004.</p>
First, I need a frameset. It will be 90% wide and 90% high, with 5% margin on all sides. This is done surprisingly easy (border is there purely to visually show the frameset).
#horizon {
position: absolute;
width: 90%;
height: 90%;
top: 5%;
left: 5%;
overflow: hidden;
display: block;
border: 1px solid #000;
}
Then comes the main, content column. The hardest thing here is to define how wide you want it to be. Really. To take care of scrolling, just add proper overflow.
#content {
position: absolute;
width: 80%;
height: 100%;
top: 0;
left: 0;
overflow: auto;
}
Navigation column is almost the same, only I align it to the right edge.
#nav {
position: absolute;
width: 20%;
height: 100%;
top: 0;
right: 0;
}
You can easily add more columns. Since all of this is absolutely positioned, just use proper width and left/right and/or height and top/bottom combinations. This simple thing was all I needed.
Last is the footer, which should be located at the bottom.
#footer {
margin: 0;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 1.5em;
display: block;
}
And that is all for good, modern browsers. Now let’s take care of the PoC…
Win IE
The layout above is totally broken in WinIE, because it ignores the height. Luckily, it does properly move the frameset to 5% of the top and left edge (IE5/Mac doesn’t even do that).
So we need to compensate the height. First, use conditional comments to make this visible only to IE6 and below.
<!--[if lte IE 6]> <style type="text/css" media="screen, projection, tv"> </style> <![endif]-->
Then, step by step, fix the heights, using proprietary expression property.
First in the queue is frameset. We need to grab view port’s height and multiply it by 0.9 (90%). In IE5.x, we use document.body.clientHeight which returns proper value. Although this property exists in IE6, it returns 0, so we need to use document.documentElement.clientHeight instead.
#horizon {
height: expression(
(
document.body.clientHeight) ?
document.body.clientHeight * 0.9 + 'px'
:
document.documentElement.clientHeight * 0.9 + 'px'
);
}
The hardest part is over. Now that frameset has needed height, all we have to do is to fetch it and apply it to each column. Again, this can easily be customized for more columns/rows, borders, margins etc.
#nav {
height: expression( document.all.horizon.offsetHeight + 'px' );
}
#content {
height: expression( document.all.horizon.offsetHeight + 'px' );
}
That’s it. Take a look at prettier example, or build your own. Like everything else on this site, the layout is CC licensed, so take your best shoot at it.





Nice Layout, maybe I will use it soon. Thank you :)
“I tested it and it fails in IE5/Mac (horribly) and Opera 6 (less horrible). Both can be circumvented, but I don’t need that.”
I’d be interested to hear a hint of how they can be circumvented, if other users need to adapt your design to accommodate those browsers.
The easiest way is to deliver non-styled version of the page to those browsers. For IE/Mac is easy, using comment hack, while Opera 6 is way more complicated, although doable using its own hacks.
I’m very positive it’s doable, although I never tried to make this work with those browsers.
Maybe a bit of “see/can’t see” with position:absolute could do the trick — they will not see the framed layout, but could still see other styles (headers and stuff).
This layout was made as CD layout for local computer magazine for PCs, so I did not have to cover those two. I don’t really like layouts that leave some customers in dark, but other things gets higher priority at the moment.