I have already came across some explanations, including stackoverflow, but unfortunately, I still can\'t understand perfectly what is the cause of it.
So, can someon
A margin is a minimal distance between an element and other elements in the same context. Floated elements are basically completely "taken out of context". They don't count for margin calculations. Any element calculating its position relative to other elements based on margins ignores floated elements entirely. So it's not that clear: both
plus margin
doesn't work, it's that margin
ignores floated elements.
The clear: both
merely causes the element to drop below all previous floated elements, its margin calculation does not push it further down because floated elements are ignored in margin calculations.
+-------------------+
| |
| display: block |
| |
+-------------------+
+--------+
--- | |
| | float: |
margin XYZ | | right |
| | |
--- +--------+
+-------------------+ <-- effect of clear: both
| |
| clear: both |
| margin-top: XYZpx |
| |
+-------------------+
The above margin XYZ says the element needs a minimal distance of XYZ to other regular elements. The next element that counts is the regular display: block
element, and the distance to it is plenty. The right floating element is ignored. But the right floating element causes the lower block to be pushed down below its boundary due to clear: both
.
Found this behaviour explained at w3.org:
Since a float is not in the flow, non-positioned block boxes created before and after the float box flow vertically as if the float did not exist. However, the current and subsequent line boxes created next to the float are shortened as necessary to make room for the margin box of the float.
and also here. Two examples:
<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<div style="clear: both; margin-top: 20px;">Main (the top margin is ignored for this non-positioned div)</div>
<br/><br/><br/>
<div style="float: left;">Left</div>
<div style="float: right; margin-bottom:20px;">Right (the bottom margin is used for this positioned div)</div>
<div style="clear: both;">Main</div>
http://jsfiddle.net/VQMqX/175/