3 columns fluid layout
This article on A List Apart has been a great source of inspiration for me. After taking this solution for a "test drive", I decided to implement negative margins the "other way around".
I think the major advantage of this technique is that it uses fewer non-semantic elements and one less "float". It also seems to cure small issues not listed in the original ALA's demo:
- links inside the right column appear not to be clickable in Opera 6
- there are background painting problems in MSIE
- there is one structural hack missing from the markup that makes NN6 unable to clear the left column
This new solution to create a table-less fluid three-column layout appears to be free of:
- CSS hacks
- Structural hacks for clearing (see No Clearing)
- IE/Win Conditional Comments
- Cryptic CSS rules
- Lengthy Styles Sheets
- "Best viewed in..." statements (see Browser Support)
This page shows the basic technique, but I have created a more "sophisticated" design based on this solution; this is the CSS challenge that "got me started".
The Logic
The image below shows how things work.
As you can see, I am shifting #container to the left instead of the right side (the opposite of what's done in the ALA article), and the most important part is that I'm not "floating" #sidebar.

The Markup
<body> <div id="outer_wrapper"> <div id="wrapper"> <div id="header"> <h2>Header</h2> <p>...</p> </div><!-- /header --> <div id="container"> <div id="left"> <h1>Left</h1> <ol> <li>...</li> <li>...</li> <li>...</li> <li>...</li> <li>...</li> </ol> </div><!-- /left --> <div id="main"> <h1>Main</h1> <p>...</p> </div><!-- /main --> <!-- This is for NN6 --> <div class="clearing"> </div> </div><!-- /container --> <div id="sidebar"> <h1>Sidebar</h1> <p>...</p> </div><!-- /sidebar --> <!-- This is for NN4 --> <div class="clearing"> </div> <div id="footer"> <h2>Footer</h2> <p>...</p> </div><!-- /footer --> </div><!-- /wrapper --> </div><!-- /outer_wrapper --> </body>
The CSS files
I am listing here only the rules related to layout.
Image names and paths are simplified
Sheet for modern browsers (how to import this sheet):
/* Copyright 2004 - 2006 - All Rights Reserved - Thierry Koblentz - www.TJKDesign.com */ #outer_wrapper { /* because "min-width" is not supported by IE, these pages use a script from PVII */ min-width:740px; /* this is to "minimize" an IE bug related to background painting, but because it creates a gap below the footer, the same declaration is also added to #footer */ width:100%; /* faux-column technique, this is the left one */ background:#fff url(left.gif) repeat-y left } #wrapper { /* faux-column technique, this is the right one */ background:url(right.gif) repeat-y right } #header { border:1px solid #b0b0b0; background:#b0b0b0; /* this is to "give layout" to the element and fix some peek-a-boo bug in IE (v6 sp2) */ width:100%; /* the above declaration creates an horizontal scroll bar in IE, this is to get rid of it */ margin:0 -1px } #container { float:left; width:100%; /* IE doubles the margins on floats, this takes care of the problem */ display:inline; /* this is where Ryan Brill (author of the ALA's article) and I go in "opposite directions" */ margin-left:-200px } #left { float:left; width:150px; /* IE doubles the margins on floats, this takes care of the problem */ display:inline; margin-left:200px } #main { /* the width from #left (150px) + the negative margin from #container (200px) */ margin-left:350px } /* good to know: if #sidebar is to be shorter than #main, then there is no need for this rule */ #sidebar { /* this is to keep the content of #sidebar to the right of #main even if the content of "main is shorter */ padding-left:100%; /* this is to "bring back" the #sidebar that has been moved out of the viewport because of the padding value */ margin-left:-200px } #sidebar p { /* this is to make sure IE (v6 sp2) *displays* this element (same problem as #header, but using a different fix) */ position:relative } #footer { /* see #outer_wrapper */ width:100%; /* this is to clear #container */ clear:both; border-top:1px solid #b0b0b0; border-bottom:1px solid #b0b0b0; background:#b0b0b0} /* this is the class that is applied to 2 structural hacks in the markup. The first "meaningless" element is used to clear #left in NN6 and the last one is used to clear #container in NN4 */ .clearing {height:0;clear:both}
As you can see, a few declarations in here are only used to "fix" MSIE/Win; if you decide to implement this technique, my advice is to remove these declarations from the Sheet to include them in a Conditional Comment.
Sheet for v4- browsers (how to import this sheet):
Because of NN4, it is important to use root relative paths to images in Styles Sheets.
Modern browsers ignore these styles because I am using a script to serve this Sheet to old browsers.
/* Copyright 2004 - 2006 - All Rights Reserved - Thierry Koblentz - www.TJKDesign.com */ #outer_wrapper { /* faux column technique: this background image "contains" the left column */ background-image:url(/root relative path/outer_wrapper.gif); background-repeat:repeat-y; border:1px solid #b0b0b0 } #header,#footer { /* this is to "force" a 100% value */ width:150%; /* the background declaration is a trick to make NN4 paint the background color in the whole DIV, not just behind its content */ background:#b0b0b0 url(/root relative path/clear.gif) } #container { /* this is to make sure NN4 doesn't paint a background image in this element */ background-image:none; float:left; width:auto; /* both padding and margin are needed to leave room for #sidebar */ margin-right:160px; padding-right:160px } #left { float:left; width:140px } #main { /* with NN4, background declarations are very important when it comes to positioning elements. The layout breaks if NN4 doesn't have an image to paint in the background of this element */ background-image:url(/root relative path/clear.gif); /* this is to keep the wrapper inside the viewport */ margin:0 } #sidebar { /* this is the background color for #sidebar; I also make sure not to inherit any background image */ background:#ccc none; margin:0; padding:10px 0; /* with "modern" browsers this element is not a float, but it has to be for NN4 */ float:right; width:180px } /* this is the class that is applied to 2 structural hacks in the markup (see #2 and #5) */ .clearing {clear:both}




















