Dragan Babić is a designer guy who blogs on interface and information design, xhtml, css, usability, accessibility, user centric design and user experience and more.

The holy grail layout - 3 columns and a lot less problems

*Update 28.02.2007:* I have just found out recently that the fix I have came up with for this layout for IE only saves you if you have a fixed value for body padding/margin (i.e. it won’t work in a situation where you have a fixed/elastic layout centered on the page with margin:0 auto;). I suppose it is because IE falsely takes the width value from it’s parent for the margin-left:-100%;.

I suppose all css developers and standardistas have already stumbled upon the „perfect layout” dubbed the holy grail, featured first here at Glish and then revised here at A list Apart. The Glish version is very good, it has a very thorough cross-browser compatibility, but it also has some faults of it’s own which we will discuss later. The A List Apart version by Mathew Levine (check out the discussion on this article for controversy) has meant to build on the Glish version, filling it’s cavities, but it has failed at another front. Let’s see what’s it all about and how we can get the best of both worlds.

The Desired Effect

The layouts in discussion here all try to solve one problem: three columns – two fixed-width sidebars and a fluid center column, all while keeping our markup clean and semantic, and most importantly well structured. Let’s see now where two of these presented layouts fail and how we can fix it.

The Glish’s grail

Rob Chandanais’ version of the Holy Grail layout is probably the most elegant solution there is for this effect. It utilizes absolute positioning with some brain-numbingly simple usage of margins and/or padding for the effect. The basic idea is that you have your main column to which you add horizontal margins or padding with the values of widths of your sidebars to „make room” for the sidebars. Optionally you could increase the values of margins/padding of the main column for gutters – it’s up to you and your design. Now we position the sidebars absolutely, and fill up the space provided by margins/padding of the main column and there you go – a perfect solution.

Oh, wait, but what happens if my design needs a full width footer? If my main column isn’t the longest – wouldn’t sidebars overflow (or „underflow”) over the footer? Well yes actually, if your footer takes up more space than the width of the main column – most probably you will experience these ugly problems. There is no solution to this (no pure css solution, I’m sure a little JavaScript could fix the problem by controlling the height of the main column dynamically), so if you want to use this technique – you better keep your footer in the main column.

The A list Apart’s grail

This technique Mathew used is messy to say the least. It uses negative margins, relative positioning – and all that in a really confusing way. I have used this technique on one of my sites – herbiv.org (pronounced as „herbivore”) and I am sad to say that it actually doesn’t work in IE. The left sidebar keeps getting „clipped” to it’s left side, meaning that it’s positioning isn’t handled correctly by ie6. I myself to avoid this bug have been forced to make Herbiv.org’s layout completely different when viewed from ie6. As you can see, by a first glance at this technique – and in theory – everything is perfectly logical, but in a world with an Internet Explorer – it is sadly not so.

My take on the holy grail layout

Recently I have been in a situation that required the described layout – full width footer included. The project got in a really rough stage, there wasn’t enough time for building everything from scratch, testing and all the regular and necessary stuff, so I figured I’ll just hop on to one of the layout galleries, grab me one of the pre-made layouts and integrate my design into it – I wonder why I weren’t doing this before. So I went to one of such sites I had bookmarked in my del.icio.us – Layout Gala and I was presented with a plethora of layouts – I was certain I will find something for me here. There it was – the number 14.
I looked at the code, and I was amazed how simple the solution was. How didn’t I think of this first, or at least known of this technique before?! It works in Internet explorer 6 as well – sweet! So I start with integration into my design and when I was done I went to check it out in ie6, since I have made some minor tweaks along the way. Then – I froze. I got the very same glitch the A List Apart’s technique was producing – the left column was being positioned too far to the left.

Express debugging

Now I had a problem I was terrified of, and to add to it – I had practically no time to fix it. But it’s funny how your brain works when you are in a tight spot. So I started debugging, fiddling with the code and doing all the things that don’t make sense because those are the thing that usually help Internet explorer to act normally.

To make the long story short , I started to make sense of things. Let’s analyze the code from my example – it is the same layout from Layout Gala, I will be working on it just so you know that I am not using my own code here, I am just providing the fixes.

Compare the two examples: the original and the same layout with my small addition.

As you can see – all I have added is some padding to the body to provide some white-space between edges of the screen and the edges of the content, and that was all it took to ruin the layout in ie6. Now I have the left sidebar screwed up – and that is of course unacceptable. Let’s see what is going on there exactly:


body{font: 76% arial,sans-serif; margin:0; padding:0 30px; }

div#wrapper{float:left; width:100%; }
div#content{margin: 0 200px; }
div#navigation{float:left; width:200px; margin-left:-200px; }
div#extra{float:left; width:200px; margin-left:-100%; }
div#footer{clear:left; width:100%; }

We have five elements, a #wrapper which is floated to the left and has a width of 100%, a #content which has the margins that should provide space for our sidebars. Then we go to our first column named #navigation which is floated to the left, has the width of 200px (equal to the margin of #content) and a negative left margin which is pulling it in to place. We are now proceeding to #extra which we are also floating to the left, giving it a width of 200px, but we are giving it a negative left margin of -100% which is pulling it into place. Lastly we have a footer that is clearing all those floats.

Basically what is being done here is stacking of our elements with floats and using of negative margins that are pulling those elements to desired place. But ie6 won’t play nice. What I have discovered is that it takes the margin-left:-100% of the #extra and adds the padding of the body onto it, making it 60px bigger (30px + 30px = 60px). So ie6 is treating that margin as 100% + 60px. Bugger. Luckily for me – that was all I needed to know, once I knew the source of the problem, all I needed to do is apply the fix for it, and it came like this:

  1. I know that the padding of the body is causing the 60px shift of the #extra, so I remove it. Things now go back to normal.
  2. With some more experimenting I found out I can add another div as a wrapper of the whole layout – it’s called #container which will provide the gutters I need (white space from the browser’s edges), but this time with margins instead of padding, because for some reason ie6 is producing a horizontal scroll when padding is used.
  1. Now that we have our gutters, we can apply the fix for #extra and get our column in it’s place, and I do that with relative positioning it by -60px from the right.

I have used conditional comments here to serve additional markup and css rules to ie6 only, and here is our working example in action here, and here is how the code looks like now:

  (...)
  div#wrapper{float:left;width:100%}
  div#content{margin: 0 200px}
  div#navigation{float:left;width:200px;margin-left:-200px}
  div#extra{float:left;width:200px;margin-left:-100%}
  div#footer{clear:left;width:100%}
  </style>

<!—[if ie 6]> <style type="text/css"> body{ padding:0; } #extra{ position:relative; right:-60px; } #container{ margin:0 30px; } </style> <![endif]—> </head> <body> <!—[if ie 6]><div id="container"><![endif]—> <div id="header"><h1>Header</h1></div> <div id="wrapper"> <div id="content"> <p><strong>1) Content here.</strong> column long long column very long fill fill fill long text text column text silly very make long very fill silly make make long make text fill very long text column silly silly very column long very column filler fill long make filler long silly very long silly silly silly long filler make column filler make silly long long fill very.</p> <p>very make make fill silly long long filler column long make silly silly column filler fill fill very filler text fill filler column make fill make text very make make very fill fill long make very filler column very long very filler silly very make filler silly make make column column </p> <p>fill long make long text very make long fill column make text very silly column filler silly text fill text filler filler filler make make make make text filler fill column filler make silly make text text fill make very filler column very </p> <p>column text long column make silly long text filler silly very very very long filler fill very fill silly very make make filler text filler text make silly text text long fill fill make text fill long text very silly long long filler filler fill silly long make column make silly long column long make very </p> </div> </div> <div id="navigation"> <p><strong>2) Navigation here.</strong> long long fill filler very fill column column silly filler very filler fill fill filler text fill very silly fill text filler silly silly filler fill very make fill column text column very very column fill fill very silly column silly silly fill fill long filler </p> </div> <div id="extra"> <p><strong>3) More stuff here.</strong> very text make long column make filler fill make column column silly filler text silly column fill silly fill column text filler make text silly filler make filler very silly make text very very text make long filler very make column make silly column fill silly column long make silly filler column filler silly long long column fill silly column very </p> </div> <div id="footer"><p>Here it goes the footer</p></div> <!—[if ie 6]></div><![endif]—> </body> </html>

The Conclusion

You never really know what you are getting with „out of the box” stuff. This layout worked, but unfortunately only in a situation when you really want to use 100% of browser’s view port (referring to layout 14 from Layout Gala). Luckily I have managed to fix it in time and I have came up with a solution that will definitely work in ie6, ie7, Firefox and Opera (if anyone can test it in Safari and/or other browsers – please let me know), and it is actually usable in real life situations. Please feel free to use this layout and technique if you are in need of such a thing – no strings attached.

Now go enjoy your two-column-fixed-centered-main-column-liquid layout goodness, cheers! :)

2006-11-22 18:36; 7 comments

  1. ray on 06/12/06 05:27 PM comments:

    thanks for the time and effort experimenting and compiling what i think a highly desirable for real world use codes. i have been trawling around for a layout which i can adopt. unlike yours none are flexible enough in that they do not provide additional information of possible errors one could encounter if the underlining codes were to changed. i certainly would like to spend time analysing codes to various layouts floating around the web but you and i know that this is normally impossible due to time constraints. i raise my glass to you and wish you a merry xmas and a happy new year. your work will not be in vain.

  2. Dragan Babić on 06/12/06 05:58 PM comments:

    Thanks a lot Ray, I’m glad I could help, and I hope you (and others) can make use of the examples on this blog.

  3. steve phillips on 05/02/07 01:32 PM comments:

    Thanks for this Dragan – a neat solution to an annoying problem. Once you get your head around the negative margins, the Layout Gala solutions seem amazingly simple. I have just spent half an hour adding Liquid Faux Columns to them too. Now the illusion is complete….

  4. Gordon on 05/04/07 06:46 PM comments:

    Oh, SO close!

    I dropped the right hand column from your design, because I’m using a 2 column layout. I was having problems with the ALA Holy Grail in conjunction with TinyMCE; every time I moused over an MCE control the sidebar flew to the right. So I thought I’d give your solution a try. While I don’t like the non-semantic divs, and I especially don’t like the conditional comment divs, the results speak for themselves. I could use TinyMCE with this layout in IE 6 without the sidebar flying across the screeen.

    However, I hit another snag, I’m big on semantic layout and if there’s a HTML tag meant to do a certain job then I believe in using it. I have several sets of controls grouped together on the form with TinyMCE that are organized together with the fieldset…/fieldset element. It all displays as intended in other browsers, but in IE 6 the controls inside the fieldset are moved over to the right, on first glance it appears the width of the left hand side bar determines how far the controls inside fieldsets move. If I wrap the controls in divs instead the problem goes away, that means not using the semantically correct tag in favour of one that has no semantic context.

  5. Junaid on 22/04/07 11:11 PM comments:

    I am looking for a javascript fix to the Glish 3 Column ‘holy grail’ layout to make sure the center column is always the longest therefore allowing the full width footer to remain presentable.

    Can anyone help me with this please?

    isolysis [a.t.] gmail.com

  6. Busy Bee on 04/09/07 03:46 PM comments:

    hi,

    Thanks for your excellent effort and it’s true that if I play around with column widths, my site looks great in IE6/7.

    However, I looked at it via a friend’s Firefox 2.0 and the left column ends up floating over the right column —- i.e. layout breaks down.

    Is there a fix for this?

    I have now gone to look at http://www.mathesonbayley.com/holy_grail.php
    to see whether his Holy Grail fix works, although yours is probably one of the simplest and most elegant out there so…I’d rather there was a fix to yours than starting all over again!

    Please help!

    Busy Bee.

  7. ihzvflyl on 20/09/07 07:04 PM comments:

    [URL=http://tmwsrtyy.com]zielnnrx[/URL] tkctpful http://jkaypbsj.com ltmfzigc tibwuhva <a href=„http://eshbeytj.com”>nevcofoo</a>

Comments are closed for this article

Syndication

The best practices in interface design straight in your feed reader. It's all there and powered by feedburner.

Grab the feed, stay informed.

activeCollab.com

Previously

Getting around

Resources