September 5th, 2007 - by Paul OB

If you browse any CSS forums you will undoubtedly see a number of posts where the answer is: “You haven’t cleared your floats.” Although the concept behind the CSS clear property is quite simple it is still a common cause of frustration among newcomers to CSS. This article will explain when and where you need to clear floats and the reasons why this is necessary.

The Clear Property

Floated elements allow for the following HTML content to wrap alongside the float (assuming there is enough room to do so). This is commonly used in the case of an image with text wrapped around it as in newspaper column style shown in Figure 1.

Figure 1
fig1.gif

The image in this example is set to float:left thereby making the following text wrap around the image. The image does have a few margins set to create some extra space around it, but the wrapping is completely automatic as it’s a consequence of floating the element. Do note that floated content must come first in the HTML so that the text that follows in the HTML will float alongside. (If this wasn’t the case and floated content wrapped with the HTML above it then all floats would end up at the top of the monitor, which wouldn’t be very useful).

This is all very straight-forward, but problems can occur when you want a paragraph of text to start below the image and not beside it. In this case you would simply apply the clear property to the content you want to start underneath. There are five values you can use with clear and they are as follows:

clear:both – ensures that no floating content is on either side of the element.

clear:left – ensures that no floating content is to the left of the element.

clear:right – ensures that no floating content is to the right of the element.

clear:none – doesn’t clear any floats and is the default state of elements anyway and isn’t usually needed unless you need to over-ride a previous clear value. Floated elements can appear on either side of the element depending on the exact structure and given the allowance that there is room for this to happen.

clear:inherit – inherits the clear value of the parent, although IE doesn’t understand the inherit value so you will seldom have any need to use this.

In most cases you will use clear:both to completely clear all floats and allow the content to start on a new line as shown in Figure 2.

Figure 2
fig2.gif

All that was needed was to apply clear:both to the paragraph in question as follows:

  1. .nextpara{clear:both;}
  1. <p class="nextpara">This text will start under the image because the clear:property has been applied. This text will start under the image because the clear:property has been applied.</p>

Floats Are Removed From The Flow

You may be thinking at this point that if you want to move the cleared paragraph down the page a bit you could simply add a little more top margin. Let’s try that and see what happens.

  1. .nextpara{clear:both;margin-top:30px}

Something strange is happening here! Although we have applied a top margin of 30px to the paragraph it doesn’t appear to have moved at all (in Firefox) and remains the same as it did in Figure 2 above. Even more strange is that IE (including IE7) has done what we expected and moved the paragraph down the page. Look at Figure 3 to compare the differences.

Figure 3
fig3.gif

What Is Happening Here?

Ignoring IE for the moment, the problem is that floats are removed from the flow and any margin you apply to the cleared content will be in relation to the static content that is above it and not to the floated image. The static content may be the paragraph text above it, or if there is no text content above it, then the parent container will be the margin’s starting point (you must also take into account collapsing margins of course).

In essence this means that you would need to apply a top margin that is larger than the image’s height in order to be sure that it would take effect. Just to show exactly what I mean we’ll apply a top margin to the paragraph greater than the image to see what effect it has in Firefox. First we’ll remove the floated text alongside the image just to make things clearer. Then we’ll apply a margin top to the cleared paragraph that is greater than the height of the image. The image is 75px and has a 7px top margin so in order to move the text 30px below the image we need to use a margin of 112px to achieve the effect we want.

  1. .nextpara{clear:both;margin-top:112px;}

Figure 4

fig4.gif

As you can see in Figure 4 above we now get the display we wanted in all browsers except IE (see the IE section below).

However, this would cause problems if we were to add some static text alongside the float because the margin would apply to the static text and our cleared paragraph would move further down the page and we would loseWeight Exercise the 30px clearance we wanted. Figure 5 shows this in action:

Figure 5
fig5.gif

As you can see our top margin on the paragraph ignores any floated content and in all aspects behaves as if the float wasn’t there — in truth it really isn’t there because it has been removed from the flow. Before we talk about a sensible solution for this we need to first go back and explore what IE is up to in order to find a suitable answer for all browsers without the need for hacks.

Oh No, Not IE Again!

Although this margin behavior is what we should expect according to the CSS specifications, we can see that IE does not follow this method — or does it? In Figure 4 I showed what the display looked like in Firefox and below in Figure 6 we can see what IE looks like.

  1. .nextpara{clear:both;margin-top:112px;}

Figure 6
fig6.gif

To quote a well known phrase… “I don’t believe it”… IE is now behaving the same as other browsers and has applied the top margin ignoring the float. What happens then if we reduce the top margin to 30px as before? Figure 7 shows the result:

  1. .nextpara{clear:both;margin-top:30px;}

Figure 7
fig7.gif

This is crazy! All we changed was the top margin from 112px down to 30px and now our text has moved another 7px further down the page. I can see that the extra 7px height is the bottom margin on the floated image, but why it should suddenly take effect seems to be a mystery.

Further testing will reveal what is happening, but the result I’m afraid will not be very helpful to us…

The image height is 75px with margins of 7px giving us a total height of 89px (75+14). It seems that if you apply a margin-top to the cleared paragraph that is less than the height of the floated content (including margins) then this margin-top distance is increased by the floated images height (including margins). If for example you apply a margin-top of 88px to the cleared paragraph you will get text that is 88px below the image but 177px from the top of the parent (i.e 89px + 88px = 177px) as shown in figure 8.

  1. .nextpara{clear:both;margin-top:88px;}

Figure 8

fig8.gif

Now we will simply add one pixel more to the margin top to make it 89px and see what happens.

CSS:

  1. .nextpara{clear:both;margin-top:89px;}

The result is shown in Figure 9.

Figure 9
fig9.gif

WOW! Simply adding one pixel now causes the cleared paragraph to behave exactly as it does in other browsers and has dropped down to only 89px from the top of the parent and ignores the float completely! From this behavior I think we can assume that IE is adding an extra margin-top to the cleared paragraph when the height of the margin is less than the height of the floated content (plus its margins). Therefore if you specify a 30px top margin on the cleared paragraph you will actually get 30px clearance from the bottom margin of the floated image which equates to 119px from the top of the parent. As soon as the top margin on the cleared paragraph equals or exceeds the height of the floated content (plus margins) then nothing is added to the margin and you get exactly what you specify.

This really is a show stopper and is the reason that I advise against applying top margins to cleared static content as it simply will not work reliably across browsers.

The Solution

The answer in fact is pretty simple — instead of applying a margin top to the cleared paragraph you simply need to apply a margin bottom to the floated element. If you wanted the floated image to have 30px of space underneath then simply apply a bottom margin of 30px (remembering that margins on floated elements don’t collapse). It’s as simple as that!

Sorry, if you thought the answer was going to be clever, but as usual with CSS if you do things the right way then they usually work as expected. Of course you should also set a margin top on the static content above if you want to maintain a 30px distance from any text/content.

I’ve spent so long discussing the strange margin behavior on cleared elements above that I now only have time to mention one other common issue and that relates to containing floats.

Where’s My Background Gone?

A common scenario is where an image is floated and there is text to the side and perhaps the parent has a border and background colour. The usual layout is something similar to this example in Figure 10:

Figure 10
fig10.gif

Usually an author will try the following code in order to get the result shown in Figure 10.

  1. .caption{
  2. background:#fffccc;
  3. color:#000;
  4. border:1px solid #000;
  5. }
  6. .caption img {
  7. float:left;
  8. margin:7px;
  9. }
  1. <p class="caption"><img src="photo-2.jpg" width="100" height="75" /> This is a caption for this image </p>

However, they are dismayed to find that the result looks like Figure 11 in both IE and Firefox (and other browsers of course).

Figure 11

fig11.gif

As I mentioned earlier, floats are removed from the flow — this is seen above. The parent wrapper (the p tag with the yellow background) ignores the floated content as though it doesn’t exist. Indeed if we were to remove the text from the example above then all that would be left would be the top border above the image.

Therefore in order to have the parent contain our float we need to “clear the float” and give the parent something to get hold of. We could do this by using a variety of clearing methods (see links below) of which I won’t go into detail as they are well covered in the links below.

Essentially, clearing involves either placing a cleared element after the float but still within the parent, or using methods such as also floating the parent or using overflow other than visible; both of which make the parent take care of so-called invisible content such as floats.

In the simplest form you could clear an element as follows:

  1. .caption{
  2. background:#fffccc;
  3. color:#000;
  4. border:1px solid #000;
  5. }
  6. .caption img {
  7. float:left;
  8. margin:7px;
  9. }
  10. .clearer{clear:both}
  1. <div class="caption">
  2. <p><img src="photo-2.jpg" width="100" height="75" /> This is a caption for this image </p>
  3. <div class="clearer"></div>
  4. </div>

However, this fails in older Mozilla browsers due to a margin collapse bug and versions of Firefox prior to 1.5 won’t clear unless the clearer element has a specified height. This height can easily be added to the mix so we end up with a clearer style like this:

  1. .clearer{
  2. clear:both;
  3. height:1px;
  4. overflow:hidden;
  5. margin-top:-1px;
  6. }

The overflow:hidden used above is so that IE6 doesn’t increase the height to the font-size height and keeps the element to 1px height only (IE6 and under treat height as min-height and an empty element of fixed height will always be at least the font-size height in IE even if there is no content). The negative top margin then negates the effect of the 1px height in most browsers. This method is consistently applied across browsers and is a solid and sure way of clearing albeit at the expense of some non-semantic mark-up.

There are better and more semantic methods of clearing and are detailed in the links below. These days I usually use the easy clearing method (shown at the PIE site below in the first link) as it works almost everywhere. The overflow method (actually discovered by me and if it worked everywhere it would almost be the best method) is a good alternative in simple situations, but doesn’t work in IE6 and under. In complicated situations the overflow method can cause more problems than its worth but in simple situations as those in the examples we have seen today, it works very well. It should be noted that IE will auto enclose floats when the parent has “haslayout” and this can be combined with the overflow method to provide IE with a clear alternative.

I hope you’ve enjoyed this little foray into clearing and now have a slightly better understanding of what is going on. I haven’t had time to discuss other aspects such as clear:left and clear:right and other bugs and problems associated with these property values, but that can wait until another day.

Please follow the links below for various clearing methods.

Clearing Techniques:

http://www.positioniseverything.net/easyclearing.html

http://www.quirksmode.org/css/clearing.html

http://www.sitepoint.com/blogs/2005/02/26/simple-clearing-of-floats/

http://csscreator.com/?q=attributes/containedfloat.php

http://www.pmob.co.uk/temp/flclear1.htm

17 Responses to “Let’s Be Clear About This!”

1 Golgotha

Man, that’s what frustrates me about CSS, this is just the clear property and my head hurts…

It would seem to me that we need standards more than ever…

I’m just glad you are around Paul, because I can’t remember all this, fix, bug, hack stuff.

Oh, and nice new calipers, very sharp.

2 Paul OB

Hi Mark, the problem is that some aspects of CSS are quite complicated and when you look at the details of what a browser has to achieve then its not surprising that discrepancies occur.

At first sight clearing sounds simple but there are are a lot of things to take into account. Its a pain that browsers vary but it’s not surprising as even some aspects of the specifications are ambiguous.

However, as mentioned in the article if you use the right approach then a lot of the bugs/discrepancies disappear and things get easier.

(I’ve used the free calipers for so long I thought I’d pay for the upgrade :).It’s a useful tool and I have it running all day.

As a side effect of using it you will usually notice whether your IE page suffers from haslayout issues. If you have dragged the calipers across an IE page and the browser doesn’t redraw the page it usually means that there is a “haslayout” issue somewhere. This is nothing to do with calipers and would be evident on any widget (or window) that you drag across an IE page. )

3 ses5909

yet another one to bookmark! You always deliver Paul; and I LOVE your titles. They are always very catchy.

4 John

It seems that if you apply a margin-top to the cleared paragraph that is less than the height of the floated content (including margins) then this margin-top distance is increased by the floated images height (including margins).

That’s gotta be the coolest IE bug ever, it’s just so wacky! Has it been documented anywhere else?

I usually use the overflow method myself but for those situations where it won’t work for IE, display: inline-block usually does the trick.

5 Paul OB

Hi John,

I expect the bug is covered somewhere but I wouldn’t be surprised if there are other variations of it depending on the exact constructs used :).

The display:inline-block for IE is basically a “haslayout” trigger and does the same job as the height:1% hack or zoom:1.0 etc (but I guess you knew that anyway).

6 Jelena

Paul, yet another great post and another confusion explained!

Thanks a lot!

7 AutisticCuckoo

“Do note that floated content must come first in the HTML so that the text that follows in the HTML will float alongside.”

Actually, that’s not true (if I understand correctly what you’re saying). According to the CSS2.1 specification (section 9.5):

“Any content in the current line before a floated box is reflowed in the first available line on the other side of the float.”

This works according to the specification in Opera 9, but Firefox 2 and IE6 are buggy and will shift a floated box down to the next line if there is inline content before it.

8 Paul OB

Hi Tommy,

Well actually I was referring to block level content before the float, so I should have been clearer in my statement above and thanks for pointing it out 🙂

You would be surprised how many people put the float after the block level content they want to wrap around it and wonder why it doesn’t work.

As you correctly say inline content in the current line should be reflowed to the first available line on the other side of the float. Of course this is restricted to the current line and I can’t think of an example off the top of my head where this would be useful or desirable.

The only browsers that show this behavior (afaik) are Opera,safari, Konqueror and strangely enough explore 5.2mac.

As usual with CSS the devil is in the detail 🙂

9 rAm

A very useful post.! Solves some of my long standing issues in a simple way.

10 CSS - A Recipe for Success

[…] this quite simply by floating the list also, which will make it contain its child floats (see the previous article on clearing if you are not sure about this topic. So we will float the ul thus containing all children. PLAIN […]

11 healthonline

You would be surprised how many people put the float after the block level content they want to wrap around it and wonder why it doesn’t work.

12 Paul OB

@healthonline: Yes that’s a common mistake 🙂

13 arielenter

For the clear and margin-top I recommend the following:

http://www.quirksmode.org/css/clearing.html

14 Paul OB

@arielenter: That link to the quirksmode site is already at the end of the article 🙂 (btw I am mentioned in that article :))

[…] [20:43] <Paul> HenriHelveticaThis is a very old article but should help : http://www.search-this.com/2007/09/05/lets-be-clear-about-this/ […]

[…] [20:43] <Paul> HenriHelveticaThis is a very old article but should help : http://www.search-this.com/2007/09/05/lets-be-clear-about-this/ […]

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators


Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

You need to download the Flash player from Adobe

Blogs Worth Reading