Adverts
Over the last few years browser support of CSS has improved greatly. Mozilla / Firefox supports most of CSS 1 and CSS 2 and some of the features that are expected to be included in CSS 3. IE has varying levels of support with quite a few broken bits but it is far from being a dead loss.
This page will show you different ways of creating a nice looking standard layout. Due to the way CSS works the standard layout of header, content columns, footer is actually supprisingly difficult to achieve and I have, in the end chosen a solution that includes a table to lay items out. I can here people leaving already but please hear my argument for doign this.
I believe that the main reason people run away from using tables for layout is not because they are wrong but because they are called tables. If they were called grids I am sure we would use them to create grid style layouts. Ok I admit that the table / grid layout algorithum is a bit nasty but we could work on that and lets face it some of the current implimentations are very fast so speed isn't really an issue. As you will see below using relative / absolute positioning and or floats can produce the same sort of result but the cost in complexity to not use a table (for table read grid) is huge.
If you aren't aware of the problems with using CSS for layout then in non-technical terms it is this. If you absolutely position a div it removes that div from the relative positioning calculation essentially giving the absolute element no height. This means that relativly positioned elements following it will over lap it (we will see this problem in the case of footers below) or at least be awkwardly placed. "That's not a problem" I hear you cry just relatvly position everything. Sadly that won't work if you want columns becase each column will appear below the one before producing steps. The only way to make columns that line up horizontally, using only CSS, is to use absolute positioning leading to a bit of a Catch 22. There is no clean solution to this problem and numerous work-around solutions have been suggested. None of them are very nice and all rely on something that smells of a hack. I propose using a table to produce grid layouts.
End Goal
The end goal is to try and achieve the final layout with the green content section being flexible enough to accomodate varying numbers of divs in the three columns (left-menu, main-window, right-menu) and in the case of the main-window the ability to further subdivide. As you can see in the image below this goal has been achieved in a faily clean manner. Click on the image to view the actual page. I have provided screen shots as well as the code to ensure you can see what I am talking about without having to worry about different browsers rendering differenly. I am using Firefox 1.0 for the screen shots.
Side by Side Alignment
The first problem that you have to solve is aligning items side by side. You might think that this would be simple but it isn't as easy as you might think. The problem is that it requires absolute positioning which as you will see below all but stops you putting anything further down the page.
If you try and achieve this result with relative positioning you need to know the pixel height of the left hand column so that you can move the right hand column up by that much. Obviously that information is only available at rending time so you need a bit of ECMA script or such to pass the value to the right hand column. That isn't, IMHO, an acceptable solution as a fair number of people surf with scripting switched off (for very good reasons). If you don't move the right column up you end up with the right hand column in the correct place horizontally but below the left hand column creating steps.
Side by Side With Header and Footer
To prove that this system works (to some extent at least) we stick in the required header as shown below (I have also sub split the main content table for effect).
As you can see it seems to work brilliantly. Left Menu, Main Window (comprising paragraphs 1 through 3) and Right Menu are all absolutly positioned such that their top is 0px below the encompasing div and their left position is 0% 20% and 80% respectivly. The problem comes when we add a footer. The footer needs to be relativly positioned as it has to be below the longest of the three columns. This is what happens:
The footer overlaps the content window. The reason for this is because div that holds the middle section essentially has no height because all the items it contains are absolutly positioned. The correct relative position for the footer therefore is at the same height as the content div.
A CSS Solution
There is a partial solution to this problem but it imposes a fairly draconian constraint on the site. One, and only one, of the content colums can be placed relativly. This gives the content div a height and therefore the footer appears below it. This is shown below:
What's wrong with that I hear you cry it looks just like like the end goal image. Well there are two main things wrong with it. This layout assumes that the center column is going to be the longest. On most pages that will be the case but if I haven't got much to say the left or right menu may well be longer. The result is this mess:
Ok, perhaps you could add empty space to the middle column to make sure it was always the longest but I really don't want to do that. It's to much of a hack for my liking. The second problem is to do with margins. I want a margin around my content boxes to give them a little space between one another. When relativly positioned next to something that is absolutly positioned the box appears a little to high (the width of the margin to high to be precise). That is corrected by setting the top value to 2px (assuming the margin is 2px) to bring it down a little. The trouble is that the footer then needs to be dropped by 2px as well. In the above case we have two boxes that need to be dropped so the foot needs to drop 6px. As you can see the amount you need to drop the footer varies so this isn't going to work unless the site has an almost completely static layout.
Floats - An Aside
You can try using floats for this type of layout and it is possible to get something that sort of works but floats break down when the window is narrow and they can be difficult to get correctly aligned. I did try and get this layout using floats but the solution had problems. Some versions of IE also have problems with complex floats which means they are of limited use in general.
The Solution
The solution to these problems then is to use a table to create the columns. The reason this works is simply because the table forces relative members to be at the same height (you can also of course valign them to the top). Therefore everything can be relativly positioned and the footer will appear in the correct place.
I have created simple table.columns and td.columns definitions which set properties on the table such that it is used for layout only. I have included border-collapse: collapse; in table.columns because AFAIK border-spacing isn't understood by IE5. You need to make sure that padding is 0px for both the table and the cells or you will get unwanted padding. Apprently the reason we still have cellpadding and cellspacing is because CSS 1 doesn't have a replacement. In fact cellspacing and cellpadding are still in XHTML 1.0.