Margin-top does not work with clear: both
You can put two floating divs in another that got "overflow: hidden":
<div style='overflow:hidden'> <div style="float: left;">Left</div> <div style="float: right;">Right</div> </div> <div style="clear: both; margin-top: 200px;">Main Data</div> edit - To add a little to this 5-year-old answer: I believe that the reason for the confusing behavior is the somewhat complicated process of crashing the field . A good trick with the original HTML from OP is to add a CSS rule as follows:
div { border: 1px solid transparent; } Poof! Now (without my extra <div> ) it works fine! Well, besides this extra pixel from the borders. In particular, I think this is a combination of how clear: both works, and field crash rules that lead to an unexpected layout from code in OP.
change again - For a complete (and, I think, completely accurate) story, see Mark Emery a great answer . Details have some complexity that this answer obscures.
While Pointy shows how you can wrap floats in a div, alternatively you can insert an empty div between the floats and the master data section. For example:
<div style="float: left;">Left</div> <div style="float: right;">Right</div> <div style="clear: both;"></div> <div style="margin-top: 200px;">Main Data</div> This can be useful in cases where adding a wrapper div around some HTML is undesirable.
Pointy and Randall Cook have great answers. I thought I would show another solution.
<div style="float: left;">Left</div> <div style="float: right;">Right</div> <div style="float: left; clear: both; margin-top: 200px;">Main Data</div> If you make the third element "float: left;" And "clear: both;", it should have the desired effect to give the 3rd element a 200 pixel marker. Here is a link to an example.
It may also affect other elements of subsequent actions as to whether they need to swim or not. However, it may also have the desired effect.
The logic underlying this specification is the bend of the mind and involves a complex interaction of rules for resolving and collapsing fields .
You are probably familiar with the usual box of models in which the content field is contained in the pad field contained on the border in the field field:
For elements with clear a value other than none , an additional component can be added to this model: a gap.
Values other than "none" can potentially result in a decoration . The gap prevents the collapse of the margin and acts as an interval above the upper edge of the element.
In other words, the box model in these cases really looks more:
But when is clearance introduced, and how important is it? Let's start with the first of these questions. The specification says :
Calculation of the gap of the element on which “clear” is installed is performed by determining the hypothetical position of the upper edge of the element boundary. This is the position where the actual top border would be if the element's "clear" property were "none".
If this hypothetical position of the upper edge of the element boundary does not pass by the corresponding floats, then a gap is entered, and the fields are collapsed in accordance with the rules in 8.3.1.
Apply this logic to the question code. Remember, we are trying to explain the position of the third div in the code below (backgrounds added to help render):
<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: both; margin-top: 200px; background: blue;">Main Data</div> Imagine how a speculator asks us that clear set to none on the third div, and not on both . Then what would the snippet look like above?
<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: none; margin-top: 200px; background: blue;">Main Data</div> Here the third div overlaps two floating divs. But wait; why is that so? Of course, it is permissible for floating elements to overlap at the block level (on the Floats spec : "Since the float is not in the stream, the placed block blocks created before and after the floating point stream are vertical, as if the float did not exist."), but our third div has margin-top loads on it and comes after two floating divs; shouldn't two floating divs appear at the top of the body, and the third div appear 200px down, well below them?
The reason this does not happen is because the margin of the third div is minimized in the divs parent field (in this case, the body - but the same behavior happens if you wrap all three divs in the parent div). The description of discarding fields (given below with a few irrelevant data) tells us that:
The vertical margins collapse ...
Two fields are adjacent if and only if:
- both refer to block blocks in a stream that participate in the same block formatting context.
- there are no string boxes, without a gap, without laying and without borders to separate them ...
- both relate to vertically adjacent box edges, i.e. form one of the following pairs:
- the upper edge of the field and the upper edge of his first child in the stream
- ...
The third div in our example, of course, is not the first child of the body, but it is its first child in the stream. Please note that for https://www.w3.org/TR/CSS22/visuren.html#positioning-scheme :
An element is called off-stream if it floats, is absolutely positioned, or is the root element. An element is called in the stream if it does not go outside the stream.
Since the first and second divs in our example are floating, only the third div is in the stream. Thus, its upper edge adjoins the upper edge of its parent, and the fields are minimized - pressing the whole body, including two floating elements. Thus, the third div overlaps its siblings, despite having a large margin-top . Therefore, in this hypothetical case, when the third clear element is set to none , we satisfy the condition:
the edge of the upper edge of the element does not pass the corresponding floats
In this way:
and the fields are collapsed in accordance with the rules in 8.3.1
How much clearance? The specification gives the browser two options, with a few explanatory notes:
Then the gap size is set to a larger:
- The amount needed to place the boundary edge of the block, even with the lower outer edge of the lowest value that needs to be cleared.
- The amount required to place the upper boundary edge of the block in its hypothetical position.
Alternatively, the gap is set exactly to the size necessary to accommodate the boundary edge of the block, even with the lower outer edge of the lowest float to be cleaned.
Note. . Both behaviors are allowed pending evaluating their compatibility with existing web content. Future CSS specifications will require either one or the other.
Note: the gap can be negative or zero.
Before we can begin to apply these rules, we immediately get into difficulty. Remember that collapsing margin, which we had to take into account in the hypothetical case when clear was none ? Well, this does not exist in this non-hypothetical case, when we calculate the permission to use, because the existence of the gap slows down. Recall that the rules for dropping margins from 8.3.1 , cited earlier, dictate that the fields are only adjacent if:
- no lines, no clearance , no indents and no borders.
(highlighted by me). Thus, the third upper edge of the div and the upper edge of its parent no longer touch. We can simulate this pre-cleaning script in our sample fragment, while preserving clear: none , but adding padding-top: 1px to the body, which also disables crash crashes according to the above rule.
body { padding-top: 1px; } <div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: none; margin-top: 200px; background: blue;">Main Data</div> Now, unlike when the fields were destroyed, our third div is conveniently below his two floating siblings. But we have already decided, based on a hypothetical scenario, when the fields really collapsed, that it is necessary to add clearance; it remains only to choose the size of the gap so that:
place the boundary edge of the block even with the lower outer edge of the lowest float to be cleaned
And therefore, we have no choice but to apply a negative clearance to the third div to drag its upper border edge, to touch the lower outer edge (also known as the edge edge) of the floating elements above it. Thus, if floating elements have a maximum of 10px, and the third div has 200px of the top margin, -190px of resolution will be applied. This finally leads us to the final result seen by the question:
<div style="float: left; background: red;">Left</div> <div style="float: right; background: green;">Right</div> <div style="clear: both; margin-top: 200px; background: blue;">Main Data</div> (Please note that if you check the third div in the fragment above using the tools of your dev browser, you can still see 200px of the top field above the div that goes above the rest of the content - it is just that the entire field of the field is raised up by a large negative clearance .)
Simple!
Alternative solution:
In fact, you can place a
margin-bottomon floating DOWN elements under an element that hasclear: both.

Note. Having made this proposal, I must immediately cancel it, usually not a very good idea, but in some limited situations it may be appropriate;
<div class='order'> <div class='address'> <strong>Your order will be shipped to:</strong><br> Simon</br> 123 Main St<br> Anytown, CA, US </div> <div class='order-details'> Item 1<br> Item 2<br> Item 3<br> Item 4<br> Item 5<br> Item 6<br> Item 7<br> Item 8<br> Item 9<br> Item 10<br> </div> <div class='options'> <button>Edit</button> <button>Save</button> </div> </div> The panel with elements is called order-details with this css
.order-details { padding: .5em; background: lightsteelblue; float: left; margin-left: 1em; /* this margin does take effect */ margin-bottom: 1em; } In the above script, the yellow panel has a margin-top , but if it is larger than the highest float element, it won’t do anything (of course, the whole point of this question).
If you set the margin-top yellow panel to 20em, then it will be visible because the margin is calculated from the top of the outer blue field.
Instead, use "padding-top" in your main div. Or, conversely, wrap the main data div in one with the "padding-top".
Try setting the bottom margin on one of the floating elements. Alternatively, you can wrap the floats in the parent element and use css hack to clear it without additional markup .
Sometimes a combination of relative position and field can solve these problems.
I use this technique for my alignright and alignleft classes in WordPress.
For example, if I want a "bottom margin" that is respected with cleanup elements that you can use.
.alignright{ float: right; margin-left: 20px; margin-top: 20px; position: relative; top: -20px; } In your example, you can do something like
<div style="float: left;">Left</div> <div style="float: right;">Right</div> <div style="clear: both; margin-bottom: 200px; position: relative; top: 200px;">Main Data</div> 
