Skip to navigation

Clearing floats for Safari

Whilst I was cross browser testing some templates yesterday, I came across a most unusual bug in Safari; namely that if a floated element, in a floated container, is not set to clear:both, the container will not inherit the width of the interior element.

It has since been pointed out (by David Hyatt no less), that WebKit (Safari) is rendering the page correctly, and the bug more likely lies with IE, with Firefox’s behavior on my real-life example (and not the one below) for now remaining inexplicable. Needless to say, for IE compatibility, it’s worth heeding the advice in this article and clearing your inner floats — Jordan

That was simple, wasn’t it? Maybe not. Imagine you have two columns of content, using the following HTML:

<div id="container">
  <div class=”column-group”>
    <div class=”wide”>Content</div>
    <div class=”wide”>Content</div>
    <div class=”wide”>Content</div>
  </div>
  <div class=”column-group”>
    <div class=”narrow”>Content</div>
    <div class=”narrow”>Content</div>
    <div class=”narrow”>Content</div>
  </div>
</div>

And styled as so:

#container,
.column-group,
.wide,
.narrow {
  float:left;
}
#container {
  width:600px;
}
.wide {
  width:400px;
}
.narrow {
  width:200px;
}

You (well, maybe that’s a little presumptuous, let’s say I) would expect the two columns of content to fit side-by-side in the #container div, and indeed they do in Firefox and IE 6. When I came to test this in Safari however, the .wide elements sat above the .narrow ones — even though Safari was displaying both sets of interior elements the correct width.

After much investigation, and making judicious use of the fantastic new element inspector available in the nightly builds of the Safari Web Kit, I came to realise the problem was that because the interior elements were not set to clear each other, the containing .column-group was being pushed to the full width of it’s container by Safari’s attempt to position two .wide elements side by side.

As such, the fix was simple, adding clear:both to the .wide and .narrow style rules instantly fixed the problem. So remember kids, if your floats are supposed to sit in a vertical column, remember to explicitly clear them, or Safari will shout at you.

So far 3 people have argued with us about ‘Clearing floats for Safari’. Read what they've said and then add to our woes using the form below.

David Hyatt · Thursday 17th August at 22:06

This is not a bug in WebKit. It is rendering your example correctly.

I tried your example and it rendered the same in Firefox, Opera and Safari. Your analysis of the issue isn’t quite correct.

In WinIE when trying to fit floats, the browser is willing to shrink the width of a float in order to make it fit. In other browsers the shrink wrap width of the float is fixed. I believe WinIE’s behavior is incorrect according to the spec, since a float’s shrink-wrap width is computed without regards to the available line width (but uses the width of the containing block instead) and is not considered to be malleable.

You have a 600 pixel wide container that contains two floats whose widths have *not* been specified. This results in shrink wrap widths being computed for those two floats. The float with the three wide children ends up being 400 pixels wide in order to fit within 600 pixels of space. The second float with the three narrow children ends up being 600 pixels wide (with all of its floats on one line).

When float layout is done, the second float can’t fit, so has to be below the first. Rather than using clear you could just put explicit widths on your wide column group and your narrow column group (400px and 200px).

Jordan · Thursday 24th August at 10:09

Thanks for taking the time to comment David.

Firstly, let me say that perhaps my wording is a little off: I’m more than willing to accept that WebKit is rendering the page correctly, it was just that it was rendering it differently to IE6 and Firefox (and, of course, that they were doing what I wanted them to!) that I called it a bug.

Testing my example above, it seems that it does indeed render in FF as it does in Safari, though IE 6 is displaying it as I’d expect (with wide and narrow side by side).

In the much more complicated example that I discovered this problem in, Firefox (as well as IE6) displayed the wide and narrow columns side by side.

Robert Huttinger · Monday 2nd June at 13:51

I had the same issue but clear both didnt work. What DID work was forcing the height of each container. Thankfully they dint need to dynamically expand ‘:)

Love what we’ve said? Think we’re talking nonsense? Don’t worry about being polite, just let us have it. We’re not afraid of telling you that you’re talking crap, so don’t be afraid of telling us the same.