Forum Moderators: not2easy
I've recently come across a but which affects all versions of IE (including 7, making CSS filter workarounds very difficult). I am using the property overflow: hidden on a container div so that it fully encloses child floats. This works a treat in most browsers I have tried, but there seems to be a bug in IE where if the last element in the container is a float, and the element before the float is a block level element with vertical margins, the float inherits those margins.
It seems to be similar to the IE Form element inheritance bug - but is also obviously somewhat different.
I'm sure I'm not the first person to discover this bug, but I can't seem to find any info on it at all and I have been searching for a few hours now.
The HTML code below illustrates the issue. There are two container divs with overflow set to hidden, each containing a floated div. The first has no other content and encloses the float nicely. The second one has a paragraph with a bottom margin immediately before the float. The float inherits the bottom margin. If you style the paragraph to display: inline, the bug does not occur. Of course making my paragraphs inline is not a serious solution to my problem.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
<title>IE float margin inherit bug</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
</head>
<body>
<div style="width: 500px; margin: 1em auto; border: 1px solid black; font-size: 1.5em">
<div style="overflow: hidden; border: 1px solid blue;">
<div style="float: left; border: 1px solid red;">A floated div</div>
</div>
<div style="overflow: hidden; border: 1px solid blue;">
<p style="margin: 0 0 1em 0">A paragraph of text.</p>
<div style="float: left; border: 1px solid red;">A floated div</div>
</div>
</div>
</body>
</html>
[edited by: SuzyUK at 7:16 am (utc) on Feb. 24, 2007]
[edit reason] Please no URLs : see TOS #13 [WebmasterWorld.com] [/edit]
code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
<title>IE float margin inherit bug</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<style>
* { margin: 0; padding: 0; }
p { margin: 0 0 1em 0; }
#wrapper { position: absolute; left: 50%; width: 500px; margin-left: -250px; border: 5px solid yellow; font-size: 1.5em; }
.container { width: 100%; float: left; border: 1px solid blue; }
.floater { float: left; border: 1px solid red; }
</style>
</head>
<body>
<div id="wrapper">
<div class="container">
<div class="floater">A floated div</div>
</div>
<div class="container">
<p>A paragraph of text.</p>
<div class="floater">A floated div</div>
</div>
</div>
</body>
</html>
It seems to be similar to the IE Form element inheritance bug - but is also obviously somewhat different.
I've been checking out the Form bug you mention hence the delayed reply. There's a sample of it here [webmasterworld.com]
it only applies to horizontal margins on certain form elements in a particular set of circumstances -
In your case I think it's simply IE's buggy float model and it's handling of "clearance"
Add anything at all even a
after the last float and it does what you want, I think this is where you will usually see some using "clearing" elements in peoples code. ----------------------------
IE has always "stretched to contain" floats if hasLayout was set to true on the container which was usually done with a dimension. The compliant way to contain floats now is using the overflow or float properties - both of which set haslayout to true for IE, thus avoiding the need for an IE workaround. IE's hasLayout has always caused various quirks in display especially when contained floats are involved.
So you're still up against the same old problems in this case - search for an article about "easyclearing" on PIE for more info - easyclearing is not a solution in this case (apart from the bit about adding a cleared element at the end of the container) but it does help explain some previous history.. and be aware that an "clearing" element with clear:both set on it might cause other problems in a page layout which contains previous floats (like left right sidebars) and if the container itself is not floated
Your 'bug' will only occur if a float is the last thing in the "container" and the margin will be that of the nearest non-floated element preceding it.
Not new perhaps but a reminder that it can still catch us out in certain circumstances!
Suzy
I also discovered as you point out that adding any inline element afterward "fixes" the bug, but the element still takes up vertical space, leading to further layout problems. Of course you could always add a special element with zero width and/or height to do the trick, but that's adding non-semantic markup which was the situation I was attempting to avoid in the first place - I might as well just add a clearing div for that.
Instead I gave up trying to find a solution to that specific issue and found another way to achieve the same effect with totally different markup and avoiding the situation altogether.
I still find it very strange that this issue hasn't been covered by the major CSS and IE bug repositories on the web. Maybe someone else searching for the same issue will find this post and not waste time looking for a fix :p
Cheers,
Scott
I tried a search to pinpoint the exact scenario, and I do see what you mean - it's not easy to find anything specific about it. I also may be wrong about there only being one circumstance - I found a page [brunildo.org] on Bruno Fassinos site which had something very similar but the float was before the element with margin, however Bruno already uses clearing divs in the actual demo so that's extra source for a start and the recommended solution is still to add another {height: 0;} element which is what you already are aware of. (and makes two extras!)
I kinda figured you were after a CSS fix and can understand what you say about adding non semantic markup (I don't like it either) but IMO people are so used to using "clearers" firstly for FF/Opera prior to oveflow: auto becoming properly supported (floating to clear isn't always an option), and also for IE's other foibles that it's just got lost in the mists of time that they were there for one reason but sometimes they were helping mask others - the thing is once they're in the source they can be used or "hidden" via the CSS - As case in point is the amount of CMS templates that have them auto built in just in case a design/theme wants to float a column!
That link above also shows that OPERA 7/8 had the same problem (in that instance) - If you take that demo and adjust it slightly to use overflow:auto and remove the clearing div to make it as close to yours as possible - Opera7/8 is happy but IE still isn't making it virtually the same situ as yours (only the float is first) - unfortunately as far as I can see the solution is the same as it was previously - add another element, but at least this time re your code that wouldn't mean two extra elements it will still just be one.
I still find it very strange that this issue hasn't been covered by the major CSS and IE bug repositories on the web.
thanks for sharing your findings and thoughts
Suzy