Derived from an actual problem with borders and margin on my site I have made this test example which I think acts a little strange:
The margin on the outer2 element is calculated from the bottom of the element above it with no top margin applied to the outer2 element. If you add border, however, it is calculated from the bottom of the border.
Also, when bottom and top margins are applied to elements that follow each other, they collapse, that is just the way the box model works.
If you want to control the offset of an element inside another element, use padding.
body{/* just a reset to simplify example */
padding:0;
margin:0
}
.inner {
margin-top:40px;
height:40px;
width:40px;
background-color:blue;
}
#outer{
background-color:green;
height:60px;
width:60px;
}
<div id="outer">
<div class="inner">
<div class="inner">
<div class="inner">
<div class="inner">
test
</div>
</div>
</div>
</div>
</div>
Above code is a more general case of the problem you mentioned. All .inner
are having margin-top=40px
in CSS. But in reality, since there is no border involved, all the margins just collapse down to one final margin of 40px which "bubble up" outside of root parent.
Your problem is that margins are exactly what the name states: they set margins to other elements, not positioning offsets. If two elements are next to eachother, with different margins, they will be placed the highest margin apart, that way both margins are satisfied. In this case, 2 margins are present with nothing separating them, so logically they collapse.
Using padding on the .outer should solve this, or relative positioning. Margins are stricly for maintaining distances to other elements.
Because margins are evil (and tend to collapse -> is it a bug? margins of P element go outside the containig div). In your case you can simply add overflow:hidden;
to .outer
http://jsfiddle.net/yhAaQ/