In order to understand what does a block formatting context do, I\'m trying to find out what\'s going on when a BFC is not created.
I took the follo
Good question, got me thinking a lot!
There are lot of concepts at play here, so I'll get to them one by one:
Buggy IE:
Whatever is mentioned in this old article about IE can be easily ignored if you do not have to design for IE7 or IE8 compatibility mode. This behavior is due to hasLayout property used internally by IE7.
See this MSDN doc for IE7:
What is "HasLayout" and why is it important?
There are several bugs in Internet Explorer that can be worked around by forcing "a layout" (an IE internal data structure) on an element.
Clearly this is a non-standard workaround and along with brings up a lot of inconsistencies. Read about this here too.
Block Formatting Context (BFC):
Excerpts from this MDN doc:
A block formatting context is a part of a visual CSS rendering of a Web page. It is the region in which the layout of block boxes occurs and in which floats interact with each other.
BFCs are very important for positioning and clearing of floated elements- floated elements affects only within the same BFCs. When you float
an element, it is taken out of the flow and reinserted by "floating".
See the examples below:
The inside of wrapper
is a BFC where you float one div to left and another to the right.
The floated elements are reinserted into the BFC while rendering around the element that is not floated.
As you have not clear
ed the floating in the BFC, the wrapper
height will extend to the size of the element that is not floated.
body{
margin: 0;
}
*{
box-sizing: border-box;
}
.wrapper{
border: 1px solid;
}
.wrapper > * {
display: inline-block;
border: 1px solid red;
width: 33.33%;
height: 100px;
}
.left{
float: left;
}
.right{
float: right;
}
.center{
height: 50px;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right">Right</div>
</div>
See what happens when you clear
the floating in the BFC- now the heights will behave normally in the wrapper
BFC.
body{
margin: 0;
}
*{
box-sizing: border-box;
}
.wrapper{
border: 1px solid;
}
.wrapper > * {
display: inline-block;
border: 1px solid red;
width: 33.33%;
height: 100px;
}
.left{
float: left;
}
.right{
float: right;
}
.center{
height: 50px;
}
.wrapper:after{
content: '';
display: block;
clear: both;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right">Right</div>
</div>
Collapsing Margins:
Top and bottom margins of blocks are sometimes combined (collapsed) into a single margin whose size is the largest of the margins combined into it, a behavior known as margin collapsing.
Margins collapse for adjacent blocks, parent and first/last child and empty blocks. See more about margin collapsing in this MDN doc.
Also note that:
Margins of floating and absolutely positioned elements never collapse.
So what really happens here?
So now you will have understood about BFCs and also how floating containers work in first case (when you have no borders specified) - that's why floatMe
stays out of its immediate mainContent
wrapper and exactly why the height of wrapper
and mainContent
is as it looks there.
Layout and IE referred to are only in IE7 and is non-standard.
Everything else that happens is because of margin collapsing:
a. h2
and pre
margins collapse (adjacent siblings)
b. mainContent
shifts a little bit to the top to collapse with the margin on the body
(Parent and first/last child)
c. As wrapper
takes the height of mainContent
, the wrapper
height is also shifted upwards.
d. What happens when you apply borders is that the margin collapsing in (b) above is nullified! (see MDN doc above as to why)
Hope things are looking better now. Cheers!