Although I very rarely use floats nowadays, there are certain specific circumstances in which they are the only viable solution. In these rare cases, I find myself getting frustrated because they don't work in the way I think they should. So I decided to look into the rules that govern the behaviour of floats, and how to properly use them.

The Rules of Floats

There are four values the float property can be set to -

.foo {
  float: left | right | inherit | none
}

What each of these values mean for how the floated element will be positioned within its parent and the document in general is determined by the following rules -

1 - A floated element is "invisible" to its parent

For all intents and purposes, a floated element does not exist to its parent element. If a parent element has only floated children within it, it will collapse as though it is empty. This is similar to how a parent element behaves when it has an element absolutely positioned within it.

.parent {
  position: relative;
  padding: 10px;
}
.child {
  float: left 
}

Parent element collapses with only floated children element

2 - A left/right floated element will try to be as close to the top and left/right of its parent element as possible

This is the "optimal" position that a left/right floated element tries to achieve.

3 - Previously defined elements will push a floated element down

Although a floated element will try to be as close to the top of the parent element as possible, any sibling elements previously defined in the document will push the floated element down. It doesn't matter if the previously defined element is a block element or inline (if it takes up the full width of the parent).

This means that if we have a paragraph defined before or after the floating element, we will get different results.

Floated element defined before the paragraph Floated Element Defined Before Paragraph

 

Floated element defined before the paragraph Floated Element Defined After Paragraph

4 - A previously declared floated element will be given a more preferable position

The most preferable position explained in Rule 2 will be given to the floated element first defined in the markup. With right floating elements, for example, the first element defined in the HTML will be the furthest right because that is the most optimal position.

<div class="container">  
  <div class="right">1</div>
  <div class="right">2</div>
  <div class="right">3</div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
</div>  

Multiple elements floating right

5 - A position closer to the top of the parent element is preferred to a position closer to the left/right of the parent element

When there are multiple elements floating in the same direction, the subsequent elements will choose a position further away from the left/right of the parent element in order to be closer to the top of the parent element.

This means that multiple floating elements will line up side by side where possible, and will only move down below each other if the parent element's width cannot contain them.

Multiple floated elements move closer to the top

In this example, element 2 is in a more preferrable position than element 3.

6 - A floated element should not extend outside its parent element

An element floated left cannot extend outside the left outer edge of its parent element.

An element floated left should not extend outside the right outer edge of its parent element unless there is no room left.

Floating element shouldn't exted outside parent

Clearing

The clear property goes hand in hand with float. It allows us to break the change in document flow that a floating element causes. There are three values to the clear property -

.foo {
  clear: left | right | both 
}

When an element is set to clear: left, this means that the clearing element's top edge must be below any left floated elements's bottom edge. If the element is clearing both, then it's top edge must be below any floated elements.

Paragraph clearing left Paragraph Clearing Left

If an element is only clearing left or right, elements floating in the other direction are not affected by this.

<div class="container">  
  <div class="left">1</div>
  <div class="left">2</div>
  <div class="left">3</div>

  <div class="right">1</div>
  <div class="right">2</div>
  <div class="right">3</div>

  <p class="clear-left">Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
</div>  

Paragraph only clearing left

 

Clearfix

There has previously been a lot of confusion over the proper way to clear. Especially due to issues with legacy browsers. A popular clearfix solution that I use was coined by CSS Mojo. The following styles are applied to the parent element of the floated properties or any subsequently defined elements -

.cf::after {
  content:"";
  display:table;
  clear:both;
}

You can read their blog post on why they use these properties in this way, but this solution essentially creates an invisible pseudo-element for the purpose of clearing.