homepage Welcome to WebmasterWorld Guest from 54.145.183.169
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Pubcon Platinum Sponsor 2014
Home / Forums Index / Code, Content, and Presentation / CSS
Forum Library, Charter, Moderators: not2easy

CSS Forum

    
Gap between 2 divs - only in firefox
margin collapse, float and clear
vampke

10+ Year Member



 
Msg#: 4344054 posted 2:36 pm on Jul 26, 2011 (gmt 0)

Hi guys,

I am having a problem with a layout in firefox. It appears completely correct in IE9, opera 11 and chrome, but I cannot get it to work in firefox.
Apparently FF needs to add whitespace between my header and my content div.
The other browsers don't do this. The funny thing that puzzles me is that if I set the margin-top of the p in the footer div to 0 it appears correctly! Adding content in the div style=clear:both also solves the issue.
Obviously this has to do with the floating div in the content area.
I managed to solve my problem but I dont understand what the footer has to do with the whitespace between header and content.
Could anyone explain?

my html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<link href="style.css" rel="stylesheet" type="text/css" />
<body>
<div id="headerbg">
<div id="header"><h1>header</h1></div>
</div>

<div id="bg">
<div id="content">
<div id="content_col1">
<h1>Lorem Ipsum</h1>
</div>

<div style="clear:both;"></div>
</div>
<div id="footer"><p>copyright </p></div>
</div>
</body>
</html>


style.css :

#headerbg {
background-color: #555;
}

#header {
height: 110px;
margin: 0 auto;
padding: 0;
}

#bg{
background-color: #bbb;
margin: 0 ;
padding:0;
}

#content {
margin: 0 auto;
padding: 0px ;
}

#content_col1 {
float:left;
width: 285px;
margin: 0px;
padding: 0 7px 0 7px;
}

#footer {
margin: 0 auto;
padding: 0 0 30px 0px;
height:100px;
}
#footer p{
color: #121212;
font-size: 10px;
text-align:right;
padding: 120px 170px 0 0 ;
/* adding "margin-top:0" solves the issue */
}

 

rainborick

WebmasterWorld Senior Member 10+ Year Member



 
Msg#: 4344054 posted 3:35 pm on Jul 26, 2011 (gmt 0)

I think there's an error in your HTML. There's no </div> for <div id="bg">. When I added one just above <div id="footer">, the page displays as you wanted.

penders

WebmasterWorld Senior Member penders us a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month



 
Msg#: 4344054 posted 5:33 pm on Jul 26, 2011 (gmt 0)

There are certainly errors in your HTML which are quite probably throwing your layout off. However, the <div> tags look to be correctly nested as far as I can see (the last </div> closes the <div id="bg">).

You are missing an opening <html> tag and have completely omitted a <head>..</head> section in which the <link> element should go.

vampke

10+ Year Member



 
Msg#: 4344054 posted 6:10 pm on Jul 26, 2011 (gmt 0)

Okay, I snipped too many lines from the original html (which validates).
Here it is:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="description" content="" />
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="headerbg">
<div id="header"><h1>header</h1></div>
</div>

<div id="bg">
<div id="content">
<div id="content_col1">
<h1>Lorem Ipsum</h1>
</div>

<div style="clear:both;"></div>
</div>
<div id="footer"><p>copyright </p></div>
</div>
</body>
</html>

penders

WebmasterWorld Senior Member penders us a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month



 
Msg#: 4344054 posted 8:54 pm on Jul 26, 2011 (gmt 0)

<div style="clear:both;"></div>


Firefox appears to collapse this empty element (your clearing div). It's as if this element is no longer there, so the floated element is no longer being cleared. If you remove this div in other browsers then you get the same result.

The p element then moves up to fill the container and the gap you are seeing is the default top margin of the p, which is why when you set this to 0 the gap goes away.

You don't need to use clearing divs anymore. The same result can be achieved in all modern browsers by simply setting
overflow:hidden on the outer container that contains the floated elements. For IE6 you need to make sure the container also hasLayout which can be achieved by giving it width.
penders

WebmasterWorld Senior Member penders us a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month



 
Msg#: 4344054 posted 11:50 pm on Jul 26, 2011 (gmt 0)

My explanation above isn't quite right... Firefox does seem to collapse the empty clearing div to some extend, but it is still clearing the float before it. If you include some content (like &nbsp;) in the clearing div then Firefox behaves like other browsers and the white gap disappears.

The white gap is certainly the default top margin of the p. This looks like a collapsing margins [w3.org] issue, or rather a non-collapsing margins issue in the case of Firefox. If, for instance, you add a top border to the #footer then the white gap also goes away.

vampke

10+ Year Member



 
Msg#: 4344054 posted 6:45 am on Jul 27, 2011 (gmt 0)

could this be considered a bug in firefox?

penders

WebmasterWorld Senior Member penders us a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month



 
Msg#: 4344054 posted 9:50 am on Jul 27, 2011 (gmt 0)

The more I look at this, the more strange it seems. In fact, if you colour the background of the other elements then you can see that no browser is collapsing the top margin of the p in the footer - which I think is correct, because of the clearing div. This appears directly above the footer/p (in Firefox as well). However, the issue I can't explain is why this very same top margin appears to be bubbling up and causing the gap below the header as well? The top margin of the p appears to be in 2 places at the same time and for this reason I think it's a bug.

Although I'd welcome anyone else to comment on this!

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4344054 posted 4:13 pm on Jul 27, 2011 (gmt 0)

Strange indeed, and makes no sense. It's almost as if FF ""thinks" footer starts at the top of content, which FireBug clearly shows it doesn't. Remove the second h1 and it almost makes sense that the margin of the p pushes content down, you can see this in FireBug. I think it's got something to do with the display mode, you add

h1,p { display: inline; }

and it goes away too, but that messes up the layout. when you set padding:0; and margin: 120 . . . on the p, the space increases by - exactly - 120px. :-)

This one seems like it's going to have issues anyway, for one, you should only have a single h1 on a page, so the second should be h2 - but the issue is when type is resized, etc., that head is going to change in vertical size, meaning your margin-top is going to float up and down depending on the environment. I'd float it, or position it absolutely inside the div.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="description" content="" />
<style type="text/css">
#headerbg {
background-color: #555;
}

#header {
height: 110px;
margin: 0 auto;
padding: 0;
}

#bg{
background-color: #bbb;
margin: 0 ;
padding:0;
}

#content {
margin: 0 auto;
padding: 0px ;
}

#content_col1 {
float:left;
width: 285px;
margin: 0px;
padding: 0 7px 0 7px;
}

#footer {
margin: 0 auto;
padding: 0 0 30px 0px;
height:100px;
position:relative;
}
#footer p{
color: #121212;
font-size: 10px;
text-align:right;
position:absolute;
bottom:12px;
right: 12px;

}
</style>
</head>
<body>
<div id="headerbg">
<div id="header"><h1>header</h1></div>
</div>

<div id="bg">
<div id="content">
<div id="content_col1">
<h1>Lorem Ipsum</h1>
</div>

<div style="clear:both;"></div>
</div>
<div id="footer"><p>copyright </p></div>
</div>
</body>
</html>

... seems to work, that way it's always at the bottom right of footer with natural padding and margins.

penders

WebmasterWorld Senior Member penders us a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month



 
Msg#: 4344054 posted 9:08 pm on Jul 27, 2011 (gmt 0)

I still think the route cause is that empty clearing DIV. By giving it content, or if you clear the float by setting
overflow:hidden on the parent container instead then you don't get this problem.

From a (rather old, and possibly out of date) article on PIE, "How To Clear Floats Without Structural Markup [positioniseverything.net]",....
...some browsers can have trouble with certain kinds of clearing elements in some situations. Mozilla is particularly sensitive to clearing problems.


...may be some things don't change?

What version of FF are people using? I'm actually running FF 3.6 at the moment.

vampke

10+ Year Member



 
Msg#: 4344054 posted 9:39 pm on Jul 27, 2011 (gmt 0)

i'm using 5.0

penders

WebmasterWorld Senior Member penders us a WebmasterWorld Top Contributor of All Time 5+ Year Member Top Contributors Of The Month



 
Msg#: 4344054 posted 9:51 pm on Jul 27, 2011 (gmt 0)

I have since tried FF 4.0 as well - the same.

rocknbil

WebmasterWorld Senior Member rocknbil us a WebmasterWorld Top Contributor of All Time 10+ Year Member



 
Msg#: 4344054 posted 4:08 pm on Jul 28, 2011 (gmt 0)

3.6.18

The reason I shy away from overflow:hidden most of the time is it means exactly that - sometimes can truncate content. :-)

alt131 will be along shortly I imagine.

Paul_o_b

10+ Year Member



 
Msg#: 4344054 posted 4:59 pm on Jul 29, 2011 (gmt 0)

It's a very old firefox bug I believe and the top margin of the p element collapses onto its parent and then onto the main parent #bg and gives the gap you see.

In the "olden days" when we used to use empty clearer divs we would also add a height of 1px to the clearer div to stop the margin collapse effect in gecko (and then add a negative margin of 1px to offset the height. (In older gecko (<ff2) empty clearer divs would not actually clear anyway unless they had a height or content.)

Indeed even when "clearfix" came along you will notice that a full stop was added into the code which stopped this issue.

content:".";

Without that full stop then even the modern clearfix methods fails in the situation above (it seems the dot has been mislaid in the new clearfix version as it has just empty content and won't stop the margin collapse bug).

In fixed width layouts then the overflow:hidden (and haslayout for old IE) is best and easiest to use unless you want visible overflow. If you use the clearfix method then make sure you add the dot into the content property but you may find that in some circumstances this creates a little extra space at the bottom.

I would never use an empty div for clearing these days though as it is just too messy.

alt131

WebmasterWorld Senior Member 5+ Year Member



 
Msg#: 4344054 posted 6:55 pm on Jul 31, 2011 (gmt 0)

Hi vampke, welcome to css, and thanks for a code sample that illustrates the issue :)

I’m joining the party late as it took all last week to undo an engineers plan that a group of us would be telecommunications-free for the conceivable future. Now I discover everyone was having fun chasing margins. No fair ;)

I managed to solve my problem but I dont understand what the footer has to do with the whitespace between header and content.
Could anyone explain?
The previous posts identified the issues, what follows is my attempt to explain the “why” – but can you tell us what you actually did to “solve” the problem in this code – was it just setting margin:0 on <p>?

Like Paul I think the “duplicated” margin is a bug in ff, but note legacy versions of Op and ie produce the same layout. I don’t think the recommendations are clear, they have changed, and the re-wording has introduced interpretation issues. So while the duplication is wrong and there has been at least one abandoned attempt to re-write gecko to deal with margin issues, it may actually be caused by trying to satisfy conflicts within the recs themselves. Seems much easier to avoid the issue by using padding on the container rather than margins on the child.

But why is it happenings? As already identified, this is about collapsing margins [w3.org]. Specifically, the default vertical margin:1em on div#footer p – which is why margin-top:0 resolved the “gap”. Margins adjoin (and therefore may collapse) when they belong to in-flow block-level boxes in the same formatting context, and there is no border, padding, content or clearing to separate them. So display:inline corrected the gap because the margins ceased to adjoin – not because it was a display issue per se. Setting overflow:hidden on the clearing div works for the same reason, as does the position in Rocknbil's example.

In addition the margins must form specified pairs – so Paul I’m not sure the complete explanation is that the margin on div#footer p is collapsing onto div#footer, and then onto the parent div#bg as that wouldn’t create the necessary adjacent pair. Plus the clearing div is in the same block formatting context so they are separated by clearance. So I suspect the issue also involves the float, the clearing div and the relationship between <p> and its parent div#footer.

The margin
div#footer has height:100px, while the padding on div#footer p dimensions it much taller so it overflows. Margins may adjoin and collapse even if the elements are not adjacent in the html, so that means the margin on div#footer p is not collapsing with the parent, but with the margins of other elements. In this code the next adjacent margin is div#content and rolling over the “layout” diagram with the shade function activated in firebug and dragonfly indicates the top margin on the <p> is adjoining/collapsing with the bottom margin:0 on div#content.

For non-ff modern versions the collapse stops there, but that doesn’t explain why, or why the margin “bubbles” up to cause a gap between div#header and div#content in ff – or older ie and opera.

The clear
Per 9.5.2 clear:both “inhibits” margin collapsing and acts as “spacing” above the margin-top of an element. The spacing is computed by calculating the hypothetical position of the clearing div’s top border edge as if there was no clear. Expose that by setting a height and clear:none: The clearing div is positioned above div#content_col1 because it is floated and removed from the flow so other boxes flow vertically as if it did not exist. Because the margins adjoin, the clearing div has collapsed through its parents so the top border edge is in the same place as the top border edge for div#bg.

However, the point of a clear is to clear floats, so 9.5.2 specifies that if the hypothetical position does not put the clearing element below the floated element, the user agent should collapse margins per 8.3.1, then introduce clearance.

Clearance
Clearance is a “space” above margin-top and 9.5.2 provides the rules for calculating its length. However, there are two different calculation options, and both are permitted. One would place the top border edge even with the bottom of the float as most of us would expect. The other is to place the top border edge in its hypothetical position – which ff seems to be doing.

The clearing element
So now factor in the clearing div, which has a min-height and height of zero (or height: auto in ie) so per 10.6.3 computes to height:0. It has no borders or padding and no content, so its own margins adjoin and collapse. Per 8.3.1
If the top and bottom margins of a box are adjoining, then it is possible for margins to collapse through it.
Note the older recs did not limit “collapsing through” to only zero-height elements and I’m not convinced the limitation was intended for the future. But most clear “fixes” prevent this by techniques such as setting a height on the clearing element, or putting content in a pseudo element.

Why a clear can collapse, but still clear
As penders referred, the clearing div seems to collapse, but is still clearing. That is because clears clear floats, not margins. Clearance does not affect the position of the elements, only the calculations for the collapsing margins. (It does affect the layout of descendants, but there aren’t any in this code. ) Clearance may be zero, or even negative – it will still act to “clear” the float.

Explaining what we see
If clearance is calculated to place the top border edge even with the bottom of the float, the zero-height clearing div is immediately below the float. The clear clears the float and inhibits margin collapse, so no margins collapse above that point. div#content has bottom margin:0 - and we can observe it collapsing with the 1em margin on <p>.

However, if clearance is calculated to place the top border edge in its hypothetical position, and the clearing div has zero-height, both the top and bottom border edge are in the same position – as above, the top border edge for the parent div#bg. That has implications for div#content because the float is removed from the flow, and the clearing div has zero-height and/or the top margin does not collapse with div#content’s bottom margin. That means div#content is treated as having height:0, which positions its bottom border edge in the same place as the bottom border edge for the clearing div. As the clearing div has zero-height, that is the same place as the top border edge. And that means the top margin on <p> collapses through to the top margin of div#bg. Hence the gap in ff and legacy versions.

Maybe ;)

Paul_o_b

10+ Year Member



 
Msg#: 4344054 posted 9:29 am on Aug 1, 2011 (gmt 0)

Very good explanation alt131:)

Yes my explanation was a little simplistic but the result is basically the same and the margin on the p becomes the margin on #bg as it collapses through the float above ignoring the empty clearer in Firefox.

All in all it looks like another plus for using overflow:hidden to clear floats (where possible) and avoid unexpected margin issues.:)

vampke

10+ Year Member



 
Msg#: 4344054 posted 9:44 am on Aug 1, 2011 (gmt 0)

hi alt131, thanks for your very elaborate and clear explanation of this issue.

I am glad it is a bug and not my poor skills :)

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / CSS
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved