How do you deal with this float margin problem?

This problem irritates me more than any other in HTML. The bottom margin of one floated element inside another will expand the containing element’s bottom margin in Firefox, but not in IE, as in the following example:


<div style="float:left; background:blue;";>
<div style="width:150px; height:150px; float:left; margin:15px; background:red; display:inline;" <!--display:inline fixes the ie6 double-margin bug-->
</div>
</div>

Firefox 3.6:

IE 6, 7, or 8:

Adding 15px bottom-padding to the containing div fixes it in IE, but effectively doubles the bottom margin in FF. The only way I have found to deal with this is to serve that padding-bottom directive in a conditional iefix stylesheet, something I don’t like to resort to for core formatting like this.

Anybody?

To quickly fix the problem, just remove the style float:left on the inner div tag, so IE will not treat it as a floating element and will wrap it properly using the outer div.

Another solution is to remove the margin and display style property on the inner div and add padding to the outer div

Thanks for your reply.

This would work for the simplified example, but not in my real-world applications where the inner div usually has to be floated.

Another solution is to remove the margin and display style property on the inner div and add padding to the outer div

That is what I did for a long time, till one day I wanted to add a banner across the width of my containing box and found that the padding, of course, made that difficult. Since then I have designed with margins on contained elements instead of padding on the containers.

Hi,
Actually the problem does not happen in IE8. If it is happening for you then it is because you are in “compatibility mode” which is basically rendering as IE7.

It is just the IE broken float model that you are seeing.

You can fix it by setting a bottom padding on the parent and side and top margins on the child float.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Float Margin</title>

<style type="text/css">
#wrap {
    float:left;
    padding-bottom:15px;
    background:blue;
}
#wrap div {
    float:left;
    width:150px;
    height:150px;
    margin:15px 15px 0;
    display:inline;
    background:red;
}
</style>
</head>
<body>

<div id="wrap">
    <div></div>
</div>

</body>
</html>

True. My screenshot was from IE8, but it had no DTD, which would trigger compatibility mode.

You can fix it by setting a bottom padding on the parent and side and top margins on the child float.

That’s true, but I often encounter a situation where I want to float many divs on page (think of items in a “grid” layout) with the same margin-bottom applied to all of them, spacing them both from each other and the bottom of the page.

There is probably no way to accomplish this without the conditional stylesheet hack.

That’s true, but I often encounter a situation where I want to float many divs on page (think of items in a “grid” layout) with the same margin-bottom applied to all of them, spacing them both from each other and the bottom of the page.

There is probably no way to accomplish this without the conditional stylesheet hack.

No, you don’t need an IE stylesheet for that. The floats have a top margin on them so any other floats will use the top margin to space out floats above.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Float Margin</title>

<style type="text/css">
#wrap {
    float:left;
    padding-bottom:15px;
    background:blue;
}
#wrap div {
    float:left;
    width:150px;
    height:150px;
    margin:15px 15px 0;
    display:inline;
    background:red;
    [B]clear:left;[/B]
    }
</style>
</head>
<body>

<div id="wrap">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>

</body>
</html>

That example above shows a single column of floats stacked. If you need them set up as a grid like you say then you will need to take the margin off one side of the floats.

I can show you how to do that plus take care of a banner/header too if you need me to.

That is what I did for a long time, till one day I wanted to add a banner across the width of my containing box and found that the padding, of course, made that difficult. Since then I have designed with margins on contained elements instead of padding on the containers.
You could have pulled your banner into the padding with negative margins. :slight_smile:

Nine floats set up as a grid. Control IE6 margin bug by setting the margin on the opposite side of the float.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Float Margin</title>

<style type="text/css">
#wrap {
    width:495px;/*510px total with left padding*/
    margin:0 auto;
    [B]padding:0 0 15px 15px;[/B]
    [COLOR=Blue]overflow:hidden;/*contain child floats*/[/COLOR]
    background:blue;
}
#banner {
    height:100px;
    [B]margin:0 0 0 -15px;[/B]
    background:lime;
    text-align:center;
}
.float {
    float:left;
    width:150px;/*165px total with right margin */
    height:150px;
    [B]margin:15px 15px 0 0;[/B]
    background:red;
    }
</style>
</head>
<body>

<div id="wrap">
    <div id="banner">Banner</div>
    <div class="float"></div>
    <div class="float"></div>
    <div class="float"></div>
    <div class="float"></div>
    <div class="float"></div>
    <div class="float"></div>
    <div class="float"></div>
    <div class="float"></div>
    <div class="float"></div>
</div>

</body>
</html>

Why didn’t I think of that? :blush:

Seriously, this is exactly what I need. I can simply turn the existing layout upside-down, with padding on the bottom instead of the top (where it is now in all my stacked layouts) and it will work. Sometimes the solution is hiding right out in the open.

You could have pulled your banner into the padding with negative margins. :slight_smile:

I tried that. Unsurprisingly, Internet Destroyer howled and scattered my page elements all over the screen. It undoubtedly could have been fixed, but that seemed like too much trouble at the time.

Control IE6 margin bug by setting the margin on the opposite side of the float.

Why do that when putting


display:inline;

on the inner floated elements fixes the margin-doubling bug?

Thanks again for helping me see the solution! You’re the man! :slight_smile:

Control IE6 margin bug by setting the margin on the opposite side of the float.

The reason I would do that is because I can in this case. Anytime I can keep from tripping an IE bug which requires a css fix I will. Why trip the double margin bug when you don’t have to?

Granted there are times when you need a margin in the same direction as the float and then you have to use the inline fix for IE6.
It just wasn’t so in this case. :wink:

Now that works fine if your floats are all the same height but float snag problems come into play if their heights start changing. The fix for that is display:inline-block; as mentioned in that link.

Glad you got it sorted out!