Forum Moderators: not2easy

Message Too Old, No Replies

IE7: adjacent floats bug?

         

heisters

12:06 am on Jul 18, 2007 (gmt 0)

10+ Year Member



Hi all, I've been trying to fix this all day, and finally managed to boil it down.

I have a fluid width container div with a bunch of floated children. One of the children is float:left and the rest are float: right. The right children have fixed widths. The last child is wider than the previous ones and has clear: right.

It's a bit difficult to describe what's wrong, but here goes: when the distance between the left element and the right edge of the container are larger than the width of the big (last) right element, the big element aligns correctly against the right edge of the container. When the container is smaller, the big element will overlap the right edge of the container even if it has room to slide below the left element.

FF and Opera do not have the problem. IE7 does it correctly except when the container is too small for the big element AND is too big to force one of the other right elements below the left element. Once one of the small right elements goes below the left element, the big right element again correctly aligns with the right border.

Maybe just try the code below. I see the problem when the browser window is 1047px wide, not including window decorations.

Has anyone seen this? Is there a fix? Do I get a prize if there isn't? (at least then I'll have something to show for banging my head against a wall for 3 hours)

<!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" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test 2</title>
<style type="text/css">
.container {
background-color: #AAA;
width: 50%;
}
.left {
float: left;
height: 3em;
border: 1px dashed green;
}
.right {
float: right;
width: 5em;
border: 1px dashed red;
}
.big {
width: 20em;
clear: right;
}
</style>
</head>
<body>
<div class="container">
<div class="left">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
</div>
<div class="right">Foo</div>
<div class="right">Foo</div>
<div class="right">Foo</div>
<div class="right">Foo</div>
<div class="right">Foo</div>
<div class="right">Foo</div>
<div class="right big">Foo</div>
<div style="clear:both;"></div>
</div>
</body>
</html>

DrDoc

1:34 am on Jul 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Nice find!

Although the bug seems vaguely familiar, I really can't remember seeing this exact thing before. And, you know what -- there appears to be no fix for it either. At least not one I could find.

You can, however, circumvent the problem by inserting a clearing element before your

.big
element.

...
<div class="right">Foo</div>
<div style="clear:whatever;"></div>
<div class="right big">Foo</div>
...

As you will notice, it does not matter what the clear property is set to (to demonstrate, I set it to the invalid value

whatever
). Its mere presence is enough to fix the bug in IE.

You'd think that

.big:before { clear: right; }
would fix it too then ...

DrDoc

1:38 am on Jul 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Update: More interesting things.

...
<div class="right">Foo</div>
<div class="left big">Foo</div>
<div style="clear:both;"></div>
...

And, again, the same "clearing element" takes care of things.

SuzyUK

1:00 pm on Jul 18, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



hmm, you know I like a good bug to squish ;)

it appears this particular IE Bug is not squishable without an extra element of sorts, there are various documentations of this bug on Bruno Fassino's site - search phrase [google.co.uk]

The bug is present in various guises whenever float + clear are used together (on the same element) in IE. (there are 3 pages of test cases via that search!)

the main problem being for IE:

A float having the clear property (value both) only clears preceding floats of its same direction (left/right.) This fact is responsible for the wrong behaviour in the following cases:

I take it from that, though not wholly tested, that a float which also has a value of

clear:right
will only clear previous right floated elements and vice versa..

-----

I changed your sample slightly to give it widths on everything to make sure it wasn't the combination of ems (widths) and px (borders) - changed method of clearing floats to remove clearing div (optional), removed borders and used backgrounds to remove all traces of 'IE having to do calculations' - but it made no difference and in fact it also appears if you reverse the float directions

my code for ref..


CSS:
.container {
background-color: #000;
width: 480px;
float: left; /* to contain floats */
}

.left {
float: left; /* swap to show reverse effect */
width: 250px;
height: 100px;
background: #dad;
}
.right {
float: left; /* swap to show reverse effect */
width: 80px;
background: #cfc;
}

.big {
width: 320px;
/* clear: both; */ /* if you need this then any empty element before the last/big float seems to help */
}

/* extras for visual */
div {margin: 2px 5px;}
.left, .right {display: inline;} /* double margin bug workaround <IE7 */

HTML:
<div class="container">
<div class="left">Left floated container..</div>
<div class="right">Foo 1</div>
<div class="right">Foo 2</div>
<div class="right">Foo 3</div>
<div class="right">Foo 4</div>
<div class="right">Foo 5</div>
<div class="right">Foo 6</div>
<!--<br />-->
<div class="right big">Foo last</div>
</div>

apparently any empty element inserted before the cleared element will do it,

HOWEVER bugs aside and with ref your particular usage, do you need the clear at all?

if you don't use clear and the big element fits the space all is well, but then IF the big element is bigger than the space between the main float and the right edge it automatically clears the space and the main float as far as I can see - perhaps there is another reason for this that I can't see or it's because of the changes I made, if so I apologise for going off tack ;)

Well spotted on the bug though!

Suzy

added to clarify
where I have clear:both in my code it makes no difference if you use

clear:right;
or
clear:left;
- depending on which float directions you're testing, I did test this but forgot to swap it back to right for this sample

[edited by: SuzyUK at 1:09 pm (utc) on July 18, 2007]

heisters

4:11 pm on Jul 23, 2007 (gmt 0)

10+ Year Member



Thanks so much, you both shed a lot of light on the subject. I'm a little clearer what exactly is going on now, so I'll try a couple of your suggested fixes when I get a chance. Unfortunately it'll be a few days until I'm back on this project, but I'll be sure to post my findings here.

Thanks again!