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.

Historically, floating was also utilized to achieve many different types of layouts in CSS. Floating was a feature in CSS that, for a long time, carried way more weight than it was designed to. Luckily we have better techniques for these things now. In modern CSS, floats are only needed for their original intended purpose.

Here we'll break down exactly what happens when floating an element with some simple examples.

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

element {
  float: left;
}

That's it, although 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; we use auto margins for that.

none is the default, so you'd only need it when overriding a previously defined float setting on an element (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 to just the size of its contents.
  2. <element> moves as high as possible within its container.
  3. Elements that come after <element> move up and flow around it so long as there's enough room to the side.
  4. <element> becomes block-level even if it normally would be an inline element.
  5. However, unlike normal block elements, <element> does not share margins with anything around it.
  6. Floated elements get partially removed from the document flow. This means that their container does not include them when determining how tall it needs to be. This is the only aspect of floats that's a little bit tricky.

The Fish Tank

When you float an element, think of its container 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:

HTML:

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

CSS:

/* backgrounds and borders omitted */

.fishtank {
    min-height: 300px;
}

.fishtank > div {
    margin: 5px;
    padding: 35px 20px;
    text-align: center;
}
Div
  • Note that I gave the tank a min-height just to illustrate things, 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 as well.
  • Like normal, the div stretches as wide as its container.

Here's what happens when we float it:

HTML:

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

CSS:

/* floating div */

.floatme {
  float: left;
}
Floating Div
  • The div shrinks to the size of its contents (including its padding).
  • It floats up until it bumps 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:

HTML:

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

CSS:

/* 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:

HTML:

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

CSS:

/* floating div */

.floatme {
  float: left;
}

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.

  • The floating div moves up at high as it can until it bumps into another block element. Since the first paragraph is a normal block element, our floating div hits its 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 both the edge of the tank and the paragraph text from touching it.
  • 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

Mostly images, but potentially block quotes or any element 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

Nope, we use CSS Grid for that now, although this method may still be used as a fallback for old browsers.

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 nice because it's pretty 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 keep the grid from reflowing, we'd simply set a width on the container. However, when determining the container width, you have to add up the floated elements' width, padding, borders, and margins. CSS Grid handles all that math for us!

Two (Multi) Column Layouts

Nope, we use CSS Grid for this too now! Floating elements to create multi-column layouts was the most common method until the recent (officially march 2017) support of CSS Grid.

This method may still be used as a fallback for older browsers.

The Tricky Bit: 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 being immediately obvious. This can cause lots of wacky problems with your layout!

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

<div class="fishtank">
    <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!

As of 2020 there is now an easy way to handle this, with cross-browser support. Here's a full example of the CSS needed to properly float an element:

HTML:

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

CSS:

.fishtank {
  display: flow-root;
}

.floatme {
  float: left;
}
Floating Div

Much better!

Previous ways of dealing with this are still commonly used for maximum compatibility with older browsers, but I won't outline them in detail here. You can look them up if a project for some reason requires it. These methods include changing the overflow property on the container, adding an empty "clearing" element at the bottom of the container, or adding a pseudo-element. Further reading on this in the resources below.