Quantcast
Channel: Blue Anvil Journal » css
Viewing all articles
Browse latest Browse all 9

Experiments with floats: whats the best method of clearance?

$
0
0

Clearing FloatsWhen developing websites there is one thing I have never kept consistent; the method of clearing floats. It seems every project I take, I seem to do it a different way, well Its about time I sorted it all out in my mind.

For those with no clue about what I’m rambling on about, with CSS layouts, when you have a float inside an block-level element, it will collapse in most browsers, since floats have no dimensions. So for instance, if I had a div container with a blue background, and a float inside it, the blue background would not surround the float (and the floats contents), due to the div ignoring the height of the float.

To fix this you need to ‘clear’ the float, so the container recognises the fact the float is there, and adjusts its height accordingly.

There are many methods of doing this, personally in the past Ive used most of them, so in this article I will compare the main ones and rate them in terms of:

  • The extra markup
  • The Amount of CSS
  • Cross Browser compatibility (I’m limited to IE5-7, Opera 9, Firefox)
  • Ease to implement


Understanding the problem

To demonstrate the problem, I created a simple test page and ran it in various browsers to show what happens.

Test 1 – No clearing method, container has width

Firefox:

Firefox, no clearing

IE7

IE7, no clearing

IE6

IE6, no clearing

IE5.5

IE5.5, no clearing

IE5

IE5, no clearing

Opera 9

opera, no clearing

As you can see from the screen-shots, standards compliant browsers (firefox & opera) do not expand the container to contain the floats, whereas IE does.

This is because the container has a width, and in IE this tells the browser the element ‘hasLayout’, making it contain the floats. Making the container have layout is one of the techniques of fixing boxes in IE.

For fairness in the tests, and showing the methods, I will remove the width from the container, as in most cases containers of floats don’t have widths. I for one use a lot of ‘display:blocks’ to avoid setting the width.

Test 2 – No clearing method, container with no width (container inside a wrapper with width).

IE: (all versions did the same thing)

IE, no width or clearing

Thats more like it, Firefox and Opera have the same problem (I wont bore you with the screen-shots), but now IE faces the problem also. This is because the container doesn’t ‘have layout’ now, therefore a clearing method is needed.

Before I go into the methods of clearance, Ill just show you the web page & the code:

<?php $text='<!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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
<!--
div {margin:0;padding:0;}
p {margin:0;padding:2px;}

div#wrapper{
							background-color:#ccc;
							width:400px;
							}

div#container{
							border:3px double #000;
							background-color:#999;
							font-size:60%;
							color:#fff;
							}
div#float1{
					float:left;
					width:48%;
					background-color:#4499cc;
					border:1px dotted #222;
}
div#float2{
					float:right;
					width:48%;
					background-color:#4499cc;
					border:1px dotted #222;
}
-->
</style>
</head>
<body>
<div id="wrapper">
<div id="container">
    <div id="float1">
    		 <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc lacinia viverra mauris. Suspendisse potenti. Pellentesque a tortor in ante pharetra commodo. Aliquam erat volutpat. Nam vel turpis. Suspendisse ullamcorper mattis turpis. Vivamus placerat pretium pede. Aenean consequat. In accumsan scelerisque lectus. Aenean suscipit eleifend nulla. Donec pede. Pellentesque quis diam. Aliquam neque. Fusce facilisis, turpis sit amet congue consequat, enim est dignissim nibh, in tristique lectus enim vitae dui. In pede purus, egestas eget, volutpat sit amet, bibendum non, purus.</p>
    </div>
		<div id="float2">
    		 <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc lacinia viverra mauris. Suspendisse potenti. Pellentesque a tortor in ante pharetra commodo. Aliquam erat volutpat. Nam vel turpis. Suspendisse ullamcorper mattis turpis. Vivamus placerat pretium pede. Aenean consequat. In accumsan scelerisque lectus. Aenean suscipit eleifend nulla. Donec pede. Pellentesque quis diam. Aliquam neque. Fusce facilisis, turpis sit amet congue consequat, enim est dignissim nibh, in tristique lectus enim vitae dui. In pede purus, egestas eget, volutpat sit amet, bibendum non, purus.</p>
    </div>
</div>
</div>
</body>
</html>'; echo htmlspecialchars($text); ?>

There, now its time to look at the juicy stuff, the methods for clearing the floats.

Method 1: The ‘clear’ property

Using the clear property to clear floats is the method recommended by the W3C, and is one of the oldest methods of fixing floats. However, despite this, it is not the best solution, and does make you add a lot of extra markup to pages.

How it works

To use this method you add an element with the css property ‘clear:both’ at the bottom of the container with the floats inside it. This forces the container to stretch to fill the floats. As you can imagine, a complex layout would need a lot of these clearing elements, with can make the markup bloated & untidy.

Example code

<?php $text='<div id="wrapper">
    <div id="container">
        <div id="float1">
        		 <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc lacinia viverra mauris. Suspendisse potenti. Pellentesque a tortor in ante pharetra commodo. Aliquam erat volutpat. Nam vel turpis. Suspendisse ullamcorper mattis turpis. Vivamus placerat pretium pede. Aenean consequat. In accumsan scelerisque lectus. Aenean suscipit eleifend nulla. Donec pede. Pellentesque quis diam. Aliquam neque. Fusce facilisis, turpis sit amet congue consequat, enim est dignissim nibh, in tristique lectus enim vitae dui. In pede purus, egestas eget, volutpat sit amet, bibendum non, purus.</p>
        </div>
    		<div id="float2">
        		 <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc lacinia viverra mauris. Suspendisse potenti. Pellentesque a tortor in ante pharetra commodo. Aliquam erat volutpat. Nam vel turpis. Suspendisse ullamcorper mattis turpis. Vivamus placerat pretium pede. Aenean consequat. In accumsan scelerisque lectus. Aenean suscipit eleifend nulla. Donec pede. Pellentesque quis diam. Aliquam neque. Fusce facilisis, turpis sit amet congue consequat, enim est dignissim nibh, in tristique lectus enim vitae dui. In pede purus, egestas eget, volutpat sit amet, bibendum non, purus.</p>
        </div>
				<div style="clear:both;"></div>
    </div><!--end container-->
</div><!--end wrapper-->'; echo htmlspecialchars($text); ?>

Testing

IE 6 (same as IE 5.5-7):

IE6, clear:both

IE 5:

IE5, clear:both

Firefox:

Firefox, clear:both

Opera:

Opera, clear:both

As you can see from the results, it cured the float clearance, however there was a small amount of cut off in IE5.

Pros:

  • Widely Supported
  • Simple to understand

Cons:

  • Bloated markup
  • Sometimes you get weird results (e.g extra padding)

Overall:

  • Browser support: 8/10
  • Markup/css bloat: 2/10
  • Simplicity: 6/10
  • Overall Rating: 5/10

Method 2: Using ‘Overflow’ properties

This is the method I have been using the most, it involves adding a simple css style to the container of the floats; overflow.

This method is really simple, by using either ‘overflow:auto’ or ‘overflow:hidden’, you give the box layout, and tell the browser that it needs to contain the floats correctly. I wont go though overflow:hidden, because it often shows scrollbars (which looks nasty) so I will focus on the (in my opinion) superior overflow:hidden property.

The code

To code, add the overflow property via inline css, or optionally in your stylesheet. I will do it inline:

<div id="container" style="overflow:hidden;">

Testing

Firefox, IE7 & Opera cleared float fine.

IE6 and below did not clear the floats.

The reason that IE6 and below did not work is because they still require ‘hasLayout’ to clear the floats. How can we achieve this? By adding a width or a height.

I want to avoid setting width in this example, so I will use a hack to set the height in only IE:

<div id="container" style="overflow:hidden;  _height:1%; ">

This cures IE 6 and 5.5, so thats all the browsers except, alas, IE5 completely hides the content. A shame. To rectify this (if you care about IE5) you will most likely need to find anther way to give the container ‘hasLayout’, for example setting a width. You could set this up in conditional comments, for just IE5, and also make sure you dont give IE5 height:1%, again by using conditional comments (my article on conditional comments).

For more information on hasLayout visit this great site http://www.satzansatz.de/cssd/onhavinglayout.html.

Pros:

  • Good support
  • Easy to use
  • No markup bloat

Cons:

  • A pain to use in IE5

Overall:

  • Browser support: 5/10
  • Markup/css bloat: 9/10
  • Simplicity: 9/10
  • Overall Rating: 7/10

Method 3: FnE method

This method is called the ‘Float Nearly Everything’ method. See if yyou can guess what you have to do.

A float which contains a float automatically clears itself, in all of the browsers. This is how it works. Its called ‘nearly’ everything since the main container will not always be floated (if its centered on screen for instance) so it will need to be cleared with one of the other methods (e.g a footer with ‘clear:both’ in it.

I find this method hard to work with, and inconsistent, since using floats everywhere is awkward. Also you have to remember, you must give floats widths for them to work with this method, adding to the difficulty.

Example screenshot of method – Firefox

Firefox, FNE method

With patience this method works, but often its not worth the time it takes, when other methods exist.

Pros:

  • Can work well
  • No extra markup

Cons:

  • Complicated
  • Takes a lot of time to get right

Overall:

  • Browser support: 8/10
  • Markup/css bloat: 9/10
  • Simplicity: 3/10
  • Overall Rating: 6/10

Method 4: Pseudo :after clearfix

This is the method I have been using most recently. It uses a pseudo class (:after) to add an invisible full stop inside the container, which makes the container clear correctly. It also needs some conditional comments to make it compatible with browsers that don’t support :after (IE7) and other older browsers (e.g IE on the Mac).

This method is hard to get your head round, but it works, as I will show soon.

Dissecting the code

The first bit of code needed is some css:

.clearfix:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}
  • The ‘:after’ pseudo class makes the browser apply the style after the content of the element ‘clearfix’ is applied to.
  • The ‘content’ attribute makes the browser generate a full stop.
  • The ‘display:block’ attribute stops it defaulting to display:inline, which cannot clear elements.
  • The ‘height:0′ attribute stops it taking up space.
  • The ‘clear:both’ attribute clears the floats.
  • The ‘visibility: hidden;’ attribute makes the generated full stop hidden.

Now lets look at some browsers, implementing the code so far. I have simply added a class of ‘clearfix; to the container class like so:

<div id="container" class="clearfix">

*note remember, if you need to apply a clear fix to a div with an existing classname, just nest another clearfix div/span inside it, since you cannot have two class names in one div. To have more than one class in a div, seperate the class names with a space (thanks for spotting my error Colin).

Firefox

Firefox, Clearfix

IE6

IE6, clearfix

As you can see, its all looking hunky-dory in Firefox, however IE6 (and all the other versions of IE) fails to clear the float.

To fix this, we give the container ‘hasLayout’ via conditional comments, we also add a hack to hide it from IE MAC using the holly-hack (I don’t have the resources to test in IE MAC) like so:

<!--[if IE]>
	<style>
          /* Hides from IE-mac \*/
          * html .clearfix {height: 1%;}
          /* End hide from IE-mac */
	</style>
<![endif]-->

IE6 (same in IE5 and IE5.5)

IE6, clearfix 2

IE7

IE7, clearfix

So thats all version less than, and including, 6 done. But, o no, IE7 wont clear the floats. This is due to the face IE 7 has dropped support for the pseudo :after class, and since the holy hack doesn’t target IE 7 either, the box wont clear.

This is where the display property saves the day. We change the conditional comment code to read:

<!--[if IE]>
	<style>
          .clearfix {display: inline-block;}
          /* Hides from IE-mac \*/
          * html .clearfix {height: 1%;}
          .clearfix {display: block;}
          /* End hide from IE-mac */
        </style>
<![endif]-->

This gives IE7′s clearfix a ‘display:inline-block’, giving the clearfix ‘hasLayout’, and then resets the display property inside the hack for all the other IE versions, solving the error.

IE7

IE7, clearfix 2

And thats a wrap. All browsers are correctly clearing the floats using the clearfix class.

Pros:

  • Good browser support
  • Not a lot of extra markup
  • Simple to reuse, once implemented

Cons:

  • Needs conditional comments

Overall:

  • Browser support: 8/10
  • Markup/css bloat: 8/10
  • Simplicity: 7/10
  • Overall Rating: 8/10

Conclusion

Overall, I think that the ‘clearfix’ pseudo method is the best method, currently, for clearing floats. The clear:both method is too bulky, the FnE method is just unnecessary, and the overflow:hidden method can get messy.

Therefore I have decided to use the “clearfix” pseudo class method in future projects, as it seems to balance browser support with ease of use and markup bulk, making it my favorite technique. Blue Anvil now uses this technique (instead of the overflow method I previously used).

I hope this article was useful, and helps you to make your websites.

References / Further Reading


Viewing all articles
Browse latest Browse all 9

Latest Images

Trending Articles





Latest Images