Floating Elements

Floating (adj. or verb) elements in CSS is a very common technique. The most common use for floating is to have text that flows around an image.

What exactly happens when we float an element can be confusing when done as part of a larger set of styling rules, so I'll try to break down what floating does with some barebones examples here.

It only takes one declaration to float an element in CSS:

element {
  float: left;
}

You'll also need to make sure the parent element clears the floated content. More on that in a minute.

The Float property accepts left, right, or none. (There is no float: middle.)

none is the default, so you only need to use it when stopping an element from inheriting a float rule from somewhere else (such as in a media query).

What Floating Does

Here's what happens when you float an <element> in CSS:

  1. Unlike normal block elements that grow as wide as their container, <element> shrinks as narrow as possible.
  2. <element> moves as high as possible within its container.
  3. Elements that come after <element> move up and flow around it.
  4. <element> becomes block-level even if it normally would be an inline element.
  5. Unlike normal block elements, <element> does not share margins with anything else.
  6. Floated elements get partially removed from the document flow. This means that their container doesn't include them when determining how tall it needs to be.

The Fish Tank

When you float an element, think of its container (usually a <div>) as a fish tank.

The element, like an ice cube, floats up toward the top of the tank. It either floats all the way to the top, or it bumps into a sibling element that won't let it up any further.

Here's a plain old div in a fish tank:

<div class="fishtank">
    <div>Div</div>
</div>
/* backgrounds and borders omitted */

.fishtank {
  min-height: 300px;
}

.fishtank > div {
  margin: 5px;
  padding: 35px 20px;
  text-align: center;
}

Div
  • I gave the tank a min-height, otherwise it would only be as tall as its contents (the div inside it).
  • I added some padding and margin on the div to make it bigger.
  • Like normal, the div stretches as wide as its container.

Here's what happens when we float it:

<div class="fishtank">
    <div class="floatme">Floating Div</div>
</div>
/* floating div */

.floatme {
  float: left;
}
Floating Div
  • The div shrank to the size of its contents (including its padding).
  • It floated up until it bumped into something. In this case it was already at the top of its container.
  • The margin on the floated div is what's keeping it slightly away from the very top left corner.

Now let's add some content, first without floating anything. I'll add some paragraphs:

<div class="fishtank">
    <p>Lorem ipsum dolor sit...</p>
    <div>Div</div>
    <p>Nullam imperdiet...</p>
    <p>Curabitur convallis...</p>
</div>
/* fishtank paragraphs */

.fishtank > p {
  margin: 10px 0;
  padding: 0 10px;
}

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et sagittis purus, id dapibus urna. Ut et pellentesque orci. Nullam ut pretium dolor, ac vehicula nisi. Maecenas pharetra enim id metus.

Div

Nullam imperdiet pellentesque dolor et sodales. Fusce fermentum nec neque eu interdum. Ut varius mauris vel elit dapibus consectetur. Nullam interdum mollis lacus nec auctor. Donec ut dolor maximus, suscipit quam volutpat, dapibus eros. Cras tempus quam ut pharetra congue. Integer sit amet finibus elit, non interdum ligula. Fusce non lectus rutrum, blandit purus fermentum, commodo elit.

Curabitur convallis, diam in condimentum dignissim, felis mauris gravida ante, condimentum consequat leo neque sed lacus.

  • I gave the paragraphs some margins to separate them, and padding to keep the text away from the very edges.
  • Both the div and the paragraphs have top and bottom margins of 10px, which they're sharing.

Don't take my word for it, you can confirm that the margins are being shared using your browser developer tools.

Ok now let's float that div again and see what happens:

<div class="fishtank">
    <p>Lorem ipsum dolor sit...</p>
    <div class="floatme">Floating Div</div>
    <p>Nullam imperdiet...</p>
    <p>Curabitur convallis...</p>
</div>

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et sagittis purus, id dapibus urna. Ut et pellentesque orci. Nullam ut pretium dolor, ac vehicula nisi. Maecenas pharetra enim id metus.

Floating Div

Nullam imperdiet pellentesque dolor et sodales. Fusce fermentum nec neque eu interdum. Ut varius mauris vel elit dapibus consectetur. Nullam interdum mollis lacus nec auctor. Donec ut dolor maximus, suscipit quam volutpat, dapibus eros. Cras tempus quam ut pharetra congue. Integer sit amet finibus elit, non interdum ligula. Fusce non lectus rutrum, blandit purus fermentum, commodo elit.

Curabitur convallis, diam in condimentum dignissim, felis mauris gravida ante, condimentum consequat leo neque sed lacus.

  • Since the first paragraph is a block element and it comes before the div in the HTML, our floating div hits a ceiling there.
  • Paragraphs that come after the div in our HTML move up under the floated element, and their content (the text) flows around it.
  • Again, notice the tiny margin on the floating div, which keeps the text from bumping right up against its right edge.
  • Notice how the floating div no longer shares its margins with the margins of anything else.

Usage

So what is floating good for?

Flowing content

Images, block quotes, and elements that you want to have other content flow around. This is the main use that floating was designed for, like the example above.

Grid of Elements

Floating is a good way to create a very simple grid. Using the code from the fish tank:

<div class="fishtank">
    <div class="floatme">Floating Div</div>
    <div class="floatme">Floating Div</div>
    <div class="floatme">Floating Div</div>
    <div class="floatme">Floating Div</div>
    <div class="floatme">Floating Div</div>
    <div class="floatme">Floating Div</div>
    <div class="floatme">Floating Div</div>
    <div class="floatme">Floating Div</div>
</div>
Floating Div
Floating Div
Floating Div
Floating Div
Floating Div
Floating Div
Floating Div
Floating Div

This is great because it's fluid - it will reflow when the browser window changes size. Play with the size of the browser window on this really big fish tank to see what I mean.

To give the grid a fixed size and prevent it from reflowing, all we need to do is set a width on the container. Just remember that when determining the container width, you have to add up the floated elements' width, padding, borders, and margins.

Two (Multi) Column Layouts

Floating is also often used to create a two column layout.

We'll create a two column layout in a separate demo.

Gotchas: Masonry Grids

When creating grids using float, you can run into trouble if the grid items have varying heights.

.taller {
  padding: 0 30px;
}

Fourth div .taller:

Floating Div
1
Floating Div
2
Floating Div
3
Floating Div
4
Floating Div
5
Floating Div
6
Floating Div
7
Floating Div
8

Second div .taller:

Floating Div
1
Floating Div
2
Floating Div
3
Floating Div
4
Floating Div
5
Floating Div
6
Floating Div
7
Floating Div
8

So when you see masonry grids with different heights (e.g. Pinterest, Tumblr, etc), those are built using other methods like javascript or CSS Grid.

Gotchas: Clearfix

As mentioned in the very beginning, floating an element partially removes it from the flow of the document. A floated element's height is ignored when the container calculates how tall it needs to be.

Without backgrounds or borders on things, it's very common to have a floated element extend below the bottom of its container without noticing. This can cause lots of other wacky problems with your layout!

Watch what happens if the fishtank doesn't have a min-height:

<div class="fishtank" style="min-height: 40px">
    <div class="floatme">Floating Div</div>
</div>
Floating Div

Not cool floating div! Now you're running into other elements on the page that are supposed to be separate!

There are a few ways to fix this, and you only need to choose one.

Option 1: the Clear property

The CSS property clear prevents an element from moving up and flowing around a floated element. You can add a clearing element inside the container at the very bottom. This makes the container extend down to include the clearing element, reaching down past any floated elements in the process.

This ensures that my fish tank is at least as tall as any floating elements inside it - as it should be.

<div class="fishtank" style="min-height: 40px">
    <div class="floatme">Floating Div</div>
    <div class="clear"></div>
</div>
.clear {
  clear: both;
}
Floating Div

Try adding border: 1px solid red; to the clearing div using your browser developer tools. The clearing div has 0 height since its empty, but you'll see that it still extends the full width of its container, like a normal div.

Like the example above, the element that's doing the "clearing" doesn't have to have anything in it.

The clear property can be left, right, both, or none. The default is none.

Option 2: Set an Overflow property

Setting overflow on the parent element is another elegant solution. This is better because it doesn't require adding extra markup to your HTML.

<div class="fishtank">
    <div class="floatme">Floating Div</div>
</div>
.fishtank {
    overflow: auto;
}
Floating Div

Option 3: Add a Pseudo-Element

Finally, another way to tackle this problem is to trick the parent into clearing the floated elements by adding an empty pseudo-element through CSS. Like the overflow method, this is much cleaner than adding extra markup to the HTML.

<div class="fishtank clearfix">
    <div class="floatme">Floating Div</div>
</div>
.clearfix::after {
	content: "";
	display: table;
	clear: both;
}
Floating Div

These seem like a bunch of hacks.

They are. This is admittedly not a very well covered problem in the CSS Float spec. In the near future, there will be another solution using the upcoming CSS property display: flow-root, which is currently under development. Links in the footer.