|
|
|
![]() |
The header, colmask and footer divs are 100% wide and stacked vertically one after the other. Colmid is inside colmask and colleft is inside colmid. The three column content divs (col1, col2 & col3) are inside colleft. Notice that the main content column (col1) comes before the other columns.
Here is the HTML code: html head title /title style type=text/css /style /head body div id="header" Header goes here /div div class="colmask threecol" div class="colmid" div class="colleft" div class="col1" Column 1 goes here /div div class="col2" Column 2 goes here /div div class="col3" Column 3 goes here /div /div (colleft) /div (colmid) /div (colmask/ threecol) div id="footer" Footer goes here /div /body /html | |
|
body {margin:0; padding:0; border:0; background:#fff; width:100%; min-width:600px; font-size:90%;} a {color:#369;} a:hover {color:#fff; background:#369; text-decoration:none;} h1, h2, h3 {margin:.8em 0 .2em 0; padding:0; } p {margin:.4em 0 .8em 0; padding:0; } img {margin:10px 0 5px;} #header { clear:both; float:left; width:100%; } #header { border-bottom:1px solid #000; } #header p,#header h1, #header h2 {padding:.4em 15px 0 15px; margin:0; } #header ul {clear:left; float:left; width:100%; list-style:none; margin:10px 0 0 0; padding:0; } #header ul li {display:inline; list-style:none; margin:0; padding:0;} #header ul li a { display:block; float:left; margin:0 0 0 1px; padding:3px 10px; text-align:center; background:#eee; color:#000; text-decoration:none; position:relative; left:15px; line-height:1.3em; } #header ul li a:hover { background:#369; color:#fff; } #header ul li a.active, #header ul li a.active:hover {color:#fff; background:#000; font-weight:bold;} #header ul li a span {display:block;} #layoutdims { clear:both; background:#eee; border-top:4px solid #000; margin:0; padding:6px 15px !important; text-align:right; } .colmask {position:relative; clear:both; float:left; width:100%; overflow:hidden;} .colright, .colmid, .colleft {float:left; width:100%; position:relative;} .col1,.col2,.col3 {float:left; position:relative; padding:0 0 1em 0; overflow:hidden; } .threecol { background:#eee;} .threecol .colmid { right:25%; background:#fff;} .threecol .colleft { right:50%; background:#f4f4f4; } .threecol .col1 {width:46%; left:102%;} .threecol .col2 {width:21%; left:31%; } .threecol .col3 { width:21%; left:85%; } #footer { clear:both; float:left; width:100%; border-top:1px solid #000; } #footer p {padding:10px; margin:0; } |
1) body tag border:0; //This removes the border around the viewport in old versions of IE min-width:600px; //Minimum width of layout - remove this line if not required Note that the min-width property does not work in old versions of Internet Explorer
|
|
First of all, all three external containers (colmask,colmid,colleft) have their width set to 100%. This means they will all take the entire page width, and they would overlap each other completely if we left positioning static.
Secondly, all these containers have relative positioning, as do col1, col2, and col3. This means they will all be positioned relative to their normal position.
Third, all these containers as well as col1,col2,col3, float to the left, so their normal position will be as far to the left as free space allows.
So colmask will coincide with the browser window, and colmid, with its white background, would normally take the space from 0% to 100% just like its parent, and so would colleft with its #f4f4f4 background. Also, col2 would normally be displayed after col1 (i.e., to the right of col1) , and col3 after col2 (i.e., to the right of col2).
But because we have adjusted the postions of these elements, this is where relative positioning comes into play.
Now, fourth, because the position is relative, the left/right properties will work the way they do for relatively positioned elements.
(As a reminder, if the positioning were absolute, then the right property would set the right edge of an element relative to the right edge of its containing element, and the left property would likewise set the left edge of the element relative to the left edge of the container). N.B. It's important to note the counterintuitive functioning of these properties where the right property actually pushes the element to the left while the left property pushes it to the right. That's becuase the correct way to visualize it is to think of the right property setting the right "padding" and similarly for the left property. |
And then, fifth,colmask will still be positioned normally, but colmid, with its right:25%; property, will be pushed 25% to the left of its normal position, thus occupying the space (-25%,75%).
Sixth, then colleft will be shifted 50% to the left of its normal position due to its right:50%; property. Its normal position starts at -25% because that's where the left edge of its parent element is now located. That will make it occupy the space (-75%,25%).
|
Seventh, now we are going the put the actual columns on the screen. First comes the middle column col1. It will be pushed 102% to the right of its normal position due to its property left:102%. Its normal position is now at -75%, where we have put the left edge of its parent element colleft, so (-75%,-29%) is where col1 would normally be displayed. Adding 102%, we find that its actual position now starts at -75%+102%=27%. Since col1 has width 46%, it will stretch from 27% to 27%+46%=73%. Thus (27%,73%) is the actual range of col1. This is indeed what we want from the middle column.
Now, the left column col2 comes next. It has its position property set to left:31% and its width is 21%. So we shift it 31% to the right of its normal position. Its normal position is where its "older brother" col1 would normally end. But this "older brother" would normally start at -75% and end at -75%+46%=-29%, so the normal position of col2 is (-29%,-8%). After being right-shifted by 31% it will find its true position at (2%,23%). Our leftmost column has been placed correctly!
Finally, the rightmost column, col3, has its position property set to left:85% and its width is 21%. This means we right-shift it by 85% relative to its normal position, which starts where col2 would normally end, that is, at -8%. Therefore col 3 will actually start at 77% and being 21% wide, it will end at 98%, thus occupying its legitimate place at (77%,98%).
So finally, (2%,23%), (27,73), and (77%,98%) are, respectively, the positions of col2,col1, and col3. Notice that this positioning leaves a total of 2%+2%=4% of empty space between the columns, providing for a beautiful layout.
|
The reader may ask: why did we need to use as many as 3 containers - colmask, colmid, and colleft? The answer is that we need the same number of containers as we do columns - three. These three containers are going to be the backgrounds of each column. So in this example, colmid, which stretches from -25% to 75%, provides background for the middle column col1. Then colleft, stretching from -75% to 25% and overlapping its parent element colmid in the region (-25%,25%), will provide a background for col2. Finally, colmask, which coincides with the browser window, will be unobstructed by the other containers in the (75%,100%) region, which is enough to accomodate col3, providing the background for this column.
The overflow:hidden property of colmask chops off the overhanging containers (necessary because colmid and colleft stick out from the outermost container colmask into the negative region). But there is also a bug in IE that prevents overflow:hidden property from working properly. The solution is to include position:relative in the css code for colmask, which otherwise would be unnecessary because we weren't going to move colmask anywhere.
Another question: why do we put the middle columns first? This is not necessary, it's just that we want to tell search engines to pay more attention to the main content of the site, which presumably will be put into the middle column.
Why didn't we use horizontal padding or margins? The reason is that IE may have trouble understanding padding and margins, so we just want to accomodate mentally challenged browsers.
In this layout the background colours of each column will always stretch to the length of the longest column. How did we do that? We did it by placing the columns inside a container, which causes the container to be the height of the tallest column. But there is a caveat: all the columns as well as the container itself must float. Matthew James Taylor gives a very concise explanation of why this is the case:
"For this structure to work correctly in all browsers the container div must be floated (left or right) plus each of the column content divs must also be floated, it does not matter which way. The process of floating the content divs makes them line up horizontally across the page. Floating the container makes it stretch down to the height of the tallest column inside. If we don't float the container then the content divs will stick out of the container at the bottom and the container won't have the correct height. Actually in this example the container will end up with a height of zero if it is not floated."
This excerpt still doesn't explain why the content divs will stick out of the container and why the container will end up with a height of zero unless it is floated. But let's just assume it is so. After all, the whole thing never made any sense to begin with. Anyway, it should be clear now why we had to store column background in containers rather than in the columns themselves. Had we kept background color within the columns, the three backgounds would end up having different heights.
Finally, note that overflow:hidden property is unnecessary in colmid and colleft because normal browsers should handle the problem of wide content correctly without such precautions on our part. But then there is IE, which we are again trying to accomodate. We might also choose to expose this rule only to IE with IE conditional comments..
|
Let's say we want to have percentages x,y,z from (left to right) with "padding" a between the columns. In the example above, it would be x=21%,y=46%, z=21%, a=2%. Of course we must require that x+y+z+6a=100%. What would then be the relative positions of the elements?
In this case we must change this fragment of code as follows:
.threecol .colmid { right:25%; background:#fff;} .threecol .colleft { right:50%; background:#f4f4f4; } .threecol .col1 {width:46%; left:102%;} .threecol .col2 {width:21%; left:31%; } .threecol .col3 { width:21%; left:85%; } |
.threecol .colmid { right:z+2a%; background:#fff;} .threecol .colleft { right:y+2a%; background:#f4f4f4; } .threecol .col1 {width:y%; left:100+a%;} .threecol .col2 {width:x%; left:z+5a%; } .threecol .col3 { width:z%; left:y+z+9a%; } |
|