Why top margin of html element is ignored after floated element?

HtmlCss

Html Problem Overview


I have a page with 2 divs. The first one is floated. The 2nd one has a "clear: both" CSS declaration and a big top margin. However, when I view the page in Firefox or IE8, I don't see the top margin. It looks like the 2nd div is touching the first div, instead of being separated. Is there any way to make the top margin work properly?

I have read the CSS spec and noticed that it says "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 didn't exist.". However, I don't know what to do about that.

Here is an example:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>CSS test</title>
</head>
<body>
     <div style="float: left; border: solid red 1px">foo</div>
     <div style="clear: both; margin-top: 90px; border: solid red 1px">This div should not touch the other div.</div>
</body>
</html>

Html Solutions


Solution 1 - Html

You've correctly identified the problem. The floated <div> is no longer used to calculate the top margin, and therefor the 2 <div>'s just butt against each other. A simple way to solve this is just to wrap the 2nd <div>. This will allow the wrapper to (invisibly) butt up against the first <div>, and allow you to specify white space for it.

The trick to getting the wrapper to work right is to have the white space be internal white space. In other words, the wrapper uses padding instead of margin. This means whatever is going on outside the wrapper (like other floating elements) won't really matter.

<div style="float: left; border: solid red 1px">foo</div>
<div class="wrapper" style="clear: both; padding-top: 90px;">
    <div style="border: solid red 1px">This div should not touch the other div.</div>
</div>

Solution 2 - Html

you could simply add a div between them

<div style="float: left; border: solid red 1px">foo</div>
<div style="clear:both;"></div>
<div style="margin-top: 90px; border: solid red 1px">This div should not touch the other div.</div>

and that should take care of it.

Lots of WordPress themes (and not only) employ this technique

Solution 3 - Html

On the second <div>:

float: none; display: inline-block;

Compatibility table for browsers: http://caniuse.com/#feat=inline-block

Solution 4 - Html

An open-ended clear; without containers, nor extra <div>

Another answer was almost right, but missed a width: 100%. Here is the corrected version.

h1 {
    clear: both;
	display: inline-block;
	width: 100%;
}

Clears without this width: 100% either require the floated element to be in a well marked off container or need an extra, semantically empty <div>. Conversely, strict separation of content and mark-up requires a strict CSS solution to this problem, i.e. without any additional non-semantic HTML.

The mere fact that one needs to mark off the end of a float, does not allow for unattended typesetting.

If the latter is your goal, the float should be left open for anything (paragraphs, ordered and unordered lists etc.) to wrap around it, until a clear is encountered. In the above example, the clear is set by a new heading.

This solution gets used extensively on my website to solve the problem when the text next to a floated miniature is short and the top-margin of the next clearing object is not respected. It also prevents any manual intervention when automatically generating PDFs from the site.

Solution 5 - Html

set "float:left" on the second div

Solution 6 - Html

The problem is that the second div can only calculate a margin from a non floating element. You need to add any non floating element before you attempt to set the margin. A non breaking space or a line break outside the floated div and before the second div will work.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   <title>CSS test</title>
</head>
<body>
   &nbsp;
   <div style="float: left; border: solid red 1px; height:40px;">foo</div>
   <div style="clear: both; margin-top: 90px; border: solid red 1px">This div should not touch the other div.</div>
</body>
</html>

Solution 7 - Html

Simplest solution to vertically separate the divs without adding extra HTML: style the floated div with the margin, not the non-floated div:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>CSS test</title>
</head>
<body>
     <div style="float: left; border: solid red 1px;margin-bottom:90px">foo</div>
     <div style="clear: both; border: solid red 1px">This div should not touch the other div.</div>
</body>
</html>

You can't use margin property to vertically position block boxes relative to the float box, but the floated box can position relative to the block box.

Solution 8 - Html

another way is to add an empty paragraph with clear both after the last floated div.

<p style="clear:both"></p>

Solution 9 - Html

Add this below the floated div and above the one you want to push down the page:

<div class="clearfix"></div>

Then in your css file add:

.clearfix {clear: both;}

This in effect creates an invisible element that the margin of your second div can react against - this is something I've seen on a number of Wordpress sites. It also has the benefit of giving you somewhere (i.e. inside the clearfix div) to put any dividing elements such as borders etc.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionElias ZamariaView Question on Stackoverflow
Solution 1 - HtmlT. StoneView Answer on Stackoverflow
Solution 2 - HtmlzerolabView Answer on Stackoverflow
Solution 3 - HtmlglocswView Answer on Stackoverflow
Solution 4 - HtmlSerge StroobandtView Answer on Stackoverflow
Solution 5 - HtmlHenrik AdolfssonView Answer on Stackoverflow
Solution 6 - HtmlOrionRobillardView Answer on Stackoverflow
Solution 7 - HtmlCSSBurnerView Answer on Stackoverflow
Solution 8 - HtmlJ. MView Answer on Stackoverflow
Solution 9 - HtmlC StubbsView Answer on Stackoverflow