Help understanding three-column layout CSS and HTML

Given the following CSS:


* { outline: 1px solid red; }
.container { overflow: hidden; }
.right { float: right; width: 100px; }
.left { float: left; width: 100px; }
.middle { margin: 0 100px; }

…and the following HTML:


<div class="container">
    <div class="left">col1</div>
    <div class="right">col3</div>
    <div class="middle">col2</div>
</div>

Why is it necessary to put the “middle” element at the bottom? If I arrange the divs left, middle, right (which to me makes more logical sense), the “right” div will move to the next line. Why does this happen?

The ‘simplified’ reason is because THE TOP of floated element can be displayed no higher than their previous element IN THE SOURCE CODE. That’s the way a float behaves.
so for maximum flexibility, you’d want to float all 3 elements, which also means you would have to give a width or think of a sizing scheme for all your elements.

If I arrange the divs left, middle, right (which to me makes more logical sense), the “right” div will move to the next line. Why does this happen?
DONT think of your mark up VISUALLY. For Semantic reasons the way that makes MOST sense, would be…

‘main content (the actual stories)’, ‘secondary content ( navigation, related stories, etc’)’ ‘tertiary content (unrelated links, ads, etc)’

hope that helps

If you’re saying that my code is wrong and that all three elements need to be floated, please let me know exactly what changes to make. Do I float the middle element left or right? Do I float all three elements left? Also, what if I want to have two or four columns instead of three? Do the general layout rules still hold?

Rather than thinking of your layout in terms of “left, right, middle”, you should think along the lines of widths. More and more websites are now using CSS grids, especially with frameworks like Bootstrap also using them.

Say you want 3 equal columns, you want 3 divs of 33% width. If you want 4 columns then you simply change to 25% width divs.

I use something along the lines of this -


* {
	-webkit-box-sizing: border-box;
  	-moz-box-sizing: border-box;
  	box-sizing: border-box;
}

[class*="col-"] {
	display: block;
	float:left;
	margin: 0 0 0 1.6%;
}

[class*="col-"]:first-of-type {
	margin: 0;
}

	.col-1 {
		width: 100%;	
	}
	
	.col-2-3 {
		width: 66.1%;	
	}
	
	.col-1-3 {
		width: 32.2%;	
	}

	.col-1-4 {
		width: 25%;	
	}

	.col-1-2 {
		width: 50%;	
	}

	.col-3-4 {
		width: 75%;	
	}

Am saying that the order of your could should GENERALLY reflect what you mean to say on the webpage. That means that WHENEVER POSSIBLE, whatever is most relevant/importatnt to the topic of that page should be higher up in the source code.

One thing that you must learn about web design is that each case is different , change one thing , and all of your strategy will needs to be reconsidered. So not so much rules as guides and best practices.

What you lose by floating all columns:

  • auto width, as floated columns shrink-wrap to the size of their content, so a width needs to be given.
    What you gain:
  • extra layout flexibility. This is what i was trying to explaing earlier, but it takes some understanding of the nuances of floats.

Consider this:

if you float:left 3 elements this wild will happen:

ELEMNT1.ELEMNT2.ELEMNT3so the second element is displayed to the RIGHT of the first element, and the third is displayed to the right of of the second… see the flow happing there. When you float:right the flow is reversed the first element is on the right , the next is to the LEFT of that , and so forth. (you do have to keep in mind what I said earlier about floating elements NOT being able to be displayed any higher than anything that PRECEDES them in the SOURCE code.

Some practical examples:

THE MARKUP ( not we don’t change this much or at all, seven when we alter the order of display)

<div class="wrap">
    <div class="main">Main content</div>
    <div class="sec">secondary stuff</div>
    <div class="ter">assides and aditions</div>
</div> 


THE GENERAL CSS



.wrap{ 
overflow:hidden; /* conatins float*/
max-width:960px;
background:pink;
margin:0 auto; /* centers  it*/

}
.main {
	width:60%;
background:red;
 	}
.sec {
	width:25%;
background:cyan;
 	}
.ter {
	width:15%;
background:yellow;
	}
	.main , .sec, .ter{ 
	float:left;
	}

NOW THE MAGIC:

let say we want our secondary content on the left, our main in the middle , and our tertiary on the right, just add this CSS :


.main {
 margin-left:25%;/* malkes space for the left column*/
	}
.sec {
 margin-left:-85%;/* the sum of its width PLUS  the center column*/
	}


but if we let say we want our secondary content on the right, our main in the middle , and our tertiary on the left, just add this instead :


	.main {margin-left:15%;/* malkes space for the left column*/
}
	.sec {float:right;/* moves the sec to the right most*/
}
	.ter {margin-left:-75%; /* the sum of its width PLUS  the center column*/
}


change your mind, and want the terciary content on the middle, the sec in the middle and the main on the left?


	.sec {float:right;/* moves the sec to the right most*/
}

by now you can see how powerful this could be!
as far as adding columns, that really depends… but one way is to sub wrap column groups ( so for example main and sec wrapped in a group div and treated as ‘main’) and apply the same techniques as above

I hope that helps.