Skip to content

CSS Float Layout: From Text Wrapping to Classic Layout Solutions ​

Open a magazine and you'll see images surrounded by text, text naturally flowing on both sides of images, forming elegant typesetting effects. CSS's float property was initially designed to achieve this effect. But over time, clever developers discovered float could also be used to create multi-column layouts, so it became the main force for CSS layout for a long time.

Float's Origin and Essence ​

Float's Original Design Intent ​

In the early days of CSS specifications, webpages were mainly used to display documents. Designers wanted to have text wrap around images like in print media. This is why the float property was born.

Imagine newspaper typesetting: a news image doesn't occupy an entire row, but is embedded in text, with text flowing around the image. Float was created to achieve this effect.

html
<article>
  <img src="photo.jpg" alt="News image" class="float-img" />
  <p>
    This is news content, text will naturally flow around the image, just like
    typesetting in newspapers...
  </p>
  <p>More text content will continue to line up next to the image...</p>
</article>
css
.float-img {
  float: left; /* Image floats left */
  width: 300px;
  margin: 0 20px 20px 0; /* Leave spacing on right and bottom */
}

Why It Was Later Used for Layout ​

Although float's intention was to achieve text wrapping, before Flexbox and Grid appeared, CSS lacked good layout tools. Developers discovered that floated elements could line up on the same row, so float was "requisitioned" to create multi-column layouts, navigation bars, grid systems, etc.

This is like a small knife originally used to peel apples, because the kitchen lacks other tools, is used to cut vegetables, open cans, etc. Although it can complete tasks, it's not the most suitable tool and brings some problems.

Float Values ​

The float property has four possible values:

css
.element {
  float: none; /* Default value, not floating */
  float: left; /* Float left */
  float: right; /* Float right */
  float: inherit; /* Inherit parent element's float value */
}

None - Not Floating ​

This is the default value, element normally participates in document flow. Usually we don't need to set it explicitly, but sometimes need to override previous float settings:

css
.element {
  float: left;
}

/* Cancel float in a media query */
@media (max-width: 768px) {
  .element {
    float: none;
  }
}

Left - Float Left ​

Element will leave normal document flow, move left until touching parent container's left edge or another float element.

html
<div class="container">
  <div class="box float-left">Left floating box</div>
  <p>This text will flow on the right side of the floating box...</p>
</div>
css
.float-left {
  float: left;
  width: 200px;
  height: 150px;
  background-color: #2196f3;
  color: white;
  padding: 15px;
  margin: 0 20px 10px 0;
}

Right - Float Right ​

Element leaves document flow, moves right until touching parent container's right edge or another float element.

css
.float-right {
  float: right;
  width: 200px;
  background-color: #4caf50;
  margin: 0 0 10px 20px;
}

There's a point to note: the order of multiple right-floated elements might be opposite to what you expect.

html
<div class="container">
  <div class="box box-1">Box 1</div>
  <div class="box box-2">Box 2</div>
  <div class="box box-3">Box 3</div>
</div>
css
.box {
  float: right;
  width: 100px;
  height: 100px;
  margin: 5px;
}

On the page, the box arrangement order is: Box 3, Box 2, Box 1 (left to right). Because Box 1 first floats right to the rightmost, then Box 2 floats to Box 1's left, Box 3 then floats to Box 2's left.

Core Float Features ​

Feature 1: Removed from Document Flow ​

This is float's most important feature. When an element floats, it "leaves" normal document flow, elements behind will move up to fill its original position.

html
<div class="container">
  <div class="box normal">Normal box</div>
  <div class="box floated">Floated box</div>
  <div class="box normal">Normal box</div>
</div>
css
.box {
  width: 200px;
  height: 100px;
  margin: 10px;
}

.normal {
  background-color: #e3f2fd;
}

.floated {
  float: left;
  background-color: #ffeb3b;
}

The third normal box will move up to the second (floated) box's original position. But there's a subtle point here: although the third box moved up, the text inside it will avoid the floated box, won't be covered.

Feature 2: Line Box Avoidance (Text Wrapping) ​

Although floated elements leave document flow, they still affect line boxes. Text and inline elements will wrap around floated elements, won't be covered by floated elements.

This is why float can achieve text wrapping effect.

html
<div class="article">
  <img src="landscape.jpg" class="float-img" alt="Landscape" />
  <p>
    This is a long paragraph of text, it will naturally flow around the image.
    When text meets the floated image, it will automatically avoid it, lining up
    on the image's right side. If there's not enough space on this line, text
    will wrap to the next line to continue lining up, until it passes the
    image's bottom, then resume normal width.
  </p>
  <p>
    Second paragraph continues. If image is tall enough, this paragraph will
    also line up next to the image...
  </p>
</div>
css
.float-img {
  float: left;
  width: 350px;
  margin: 0 25px 15px 0;
  border-radius: 8px;
}

Feature 3: Floated Element Arrangement Rules ​

Multiple floated elements will arrange according to certain rules:

Rule 1: Floated elements will go as far left (or right) as possible

html
<div class="container">
  <div class="float-box">Box 1</div>
  <div class="float-box">Box 2</div>
  <div class="float-box">Box 3</div>
</div>
css
.container {
  width: 800px;
  background-color: #f5f5f5;
  padding: 10px;
}

.float-box {
  float: left;
  width: 200px;
  height: 150px;
  margin: 10px;
  background-color: #2196f3;
}

Three boxes will line up on the same row, until container width is not enough, then the fourth box will wrap to the next line.

Rule 2: Floated elements won't overlap

Floated elements won't cover each other, they will line up next to each other:

css
.box-1 {
  float: left;
  width: 200px;
}

.box-2 {
  float: left; /* Will be right next to box-1 */
  width: 250px;
}

Rule 3: A floated element's top won't be higher than the previous element's top

html
<div class="container">
  <div class="tall-box">Tall box</div>
  <div class="short-box">Short box (floated)</div>
</div>
css
.tall-box {
  height: 200px;
  background-color: #e3f2fd;
}

.short-box {
  float: left;
  width: 150px;
  height: 100px;
  background-color: #ffeb3b;
}

The floated short box won't "fly" above the tall box, its top will at most be level with the tall box's top.

Feature 4: Blockification ​

Floated elements automatically become block elements, even if they were originally inline elements.

css
span {
  /* span is originally an inline element */
  float: left;
  width: 200px; /* Can set width and height after floating */
  height: 100px;
  /* Equivalent to applying display: block automatically */
}

This means a floated <span> can set width and height, a floated <a> can also set width and height, just like block elements.

Feature 5: Width Shrinkage ​

Block elements default width is 100%, but floated block elements' width shrinks to be determined by content (similar to inline-block).

html
<div class="normal-div">I'm a normal div, width 100%</div>
<div class="float-div">I'm a floated div, width determined by content</div>
css
.normal-div {
  background-color: #e3f2fd;
  padding: 10px;
  /* Width fills parent container */
}

.float-div {
  float: left;
  background-color: #fff59d;
  padding: 10px;
  /* Width shrinks to content width */
}

If you want a floated element to have fixed width, you need to explicitly set width.

Feature 6: Height Collapse ​

This is float's most famous "side effect". When all child elements of a parent container float, the parent container will lose height, behaving as if it has no content.

html
<div class="container">
  <div class="float-box">Floated content</div>
  <div class="float-box">Floated content</div>
</div>
css
.container {
  background-color: #f5f5f5;
  border: 3px solid #2196f3;
  /* Height will collapse to 0 */
}

.float-box {
  float: left;
  width: 200px;
  height: 150px;
  margin: 10px;
  background-color: #4caf50;
}

The parent container's border will collapse to the top, background color also won't display. This is because floated elements left document flow, the parent container when calculating height considers itself "empty".

This problem is very important, we will explain various solutions in detail in the next article "Clearing Float".

Practical Float Applications ​

Application 1: Text Wrapping Images (Most Suitable Scenario) ​

This is float's job, also the most recommended scenario for using float.

html
<article class="blog-post">
  <h2>Article Title</h2>
  <img src="feature.jpg" alt="Featured image" class="featured-img" />
  <p>
    This is the first paragraph of the article, text will naturally flow around
    the image...
  </p>
  <p>Second paragraph continues...</p>
  <p>If image is finished, text resumes normal width...</p>
</article>
css
.featured-img {
  float: left;
  width: 400px;
  margin: 0 30px 20px 0;
  border-radius: 8px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.blog-post p {
  line-height: 1.8;
  margin-bottom: 20px;
}

Right-side image variant:

css
.featured-img-right {
  float: right;
  width: 350px;
  margin: 0 0 20px 30px;
}
html
<div class="photo-gallery">
  <img src="photo1.jpg" alt="Photo 1" class="gallery-img" />
  <img src="photo2.jpg" alt="Photo 2" class="gallery-img" />
  <img src="photo3.jpg" alt="Photo 3" class="gallery-img" />
  <img src="photo4.jpg" alt="Photo 4" class="gallery-img" />
  <p>These images will automatically arrange into a grid...</p>
</div>
css
.gallery-img {
  float: left;
  width: calc(25% - 20px); /* 4 column layout */
  margin: 10px;
  border-radius: 4px;
}

Application 3: Multi-column Layout (Traditional Method) ​

Before Flexbox and Grid appeared, float was the main way to create multi-column layouts.

Two-column layout (fixed sidebar + adaptive main content):

html
<div class="page">
  <aside class="sidebar">Sidebar</aside>
  <main class="content">Main content</main>
</div>
css
.page {
  max-width: 1200px;
  margin: 0 auto;
}

.sidebar {
  float: left;
  width: 300px;
  background-color: #f5f5f5;
  padding: 20px;
}

.content {
  margin-left: 340px; /* Sidebar width + spacing */
  padding: 20px;
}

Three-column layout:

html
<div class="layout">
  <aside class="left-sidebar">Left sidebar</aside>
  <main class="main">Main content</main>
  <aside class="right-sidebar">Right sidebar</aside>
</div>
css
.left-sidebar {
  float: left;
  width: 250px;
}

.right-sidebar {
  float: right;
  width: 250px;
}

.main {
  margin: 0 280px; /* Leave sidebar width + spacing on left and right */
}

Application 4: Horizontal Navigation Menu ​

html
<nav class="navbar">
  <ul class="nav-list">
    <li><a href="#">Home</a></li>
    <li><a href="#">Products</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
css
.nav-list {
  list-style: none;
  margin: 0;
  padding: 0;
  background-color: #333;
}

.nav-list li {
  float: left;
}

.nav-list a {
  display: block;
  padding: 15px 25px;
  color: white;
  text-decoration: none;
}

.nav-list a:hover {
  background-color: #555;
}

Note: Although this scenario can use float, now it's more recommended to use display: inline-block or display: flex.

Application 5: Card Grid ​

html
<div class="card-grid">
  <div class="card">Card 1</div>
  <div class="card">Card 2</div>
  <div class="card">Card 3</div>
  <div class="card">Card 4</div>
  <div class="card">Card 5</div>
  <div class="card">Card 6</div>
</div>
css
.card-grid {
  max-width: 1200px;
  margin: 0 auto;
  /* Need to clear float */
}

.card {
  float: left;
  width: calc(33.333% - 20px);
  margin: 10px;
  padding: 20px;
  background-color: white;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border-radius: 8px;
}

/* Responsive: two columns on small screens */
@media (max-width: 768px) {
  .card {
    width: calc(50% - 20px);
  }
}

/* Smaller screens: single column */
@media (max-width: 480px) {
  .card {
    width: calc(100% - 20px);
    float: none;
  }
}

Common Float Problems ​

Problem 1: Height Collapse ​

This is float's biggest problem, will be explained in detail in the next article. Simple example:

css
.container {
  background-color: #f5f5f5;
  /* Height collapse */
}

.float-child {
  float: left;
}

/* Quick solution: add overflow */
.container {
  overflow: hidden; /* Or auto */
}

Problem 2: Floated Element Misalignment ​

When floated element heights are inconsistent, misalignment may occur:

html
<div class="grid">
  <div class="item" style="height: 200px;">Tall box</div>
  <div class="item" style="height: 100px;">Short box</div>
  <div class="item" style="height: 150px;">Medium box</div>
  <div class="item" style="height: 120px;">This will get stuck!</div>
</div>
css
.item {
  float: left;
  width: 25%;
}

The fourth box might not wrap to new row top, but get stuck below the first tall box.

Solution: Clear float after each row

css
.item:nth-child(4n + 1) {
  clear: left; /* First item in each row clears float */
}

Problem 3: Excessive Text Wrapping ​

Sometimes you want content below image not to wrap, but start below image:

html
<div class="section">
  <img src="photo.jpg" class="float-img" />
  <p>This text wraps around image...</p>
  <h3 class="stop-wrapping">This heading doesn't want to wrap</h3>
</div>
css
.float-img {
  float: left;
}

.stop-wrapping {
  clear: left; /* Clear left float, no more wrapping */
}

Problem 4: Strange Margin Behavior on Floated Elements ​

Floated elements' margins don't collapse, different from block elements:

css
.float-box {
  float: left;
  margin-bottom: 20px;
}

.float-box + .float-box {
  margin-top: 20px; /* Two margins don't collapse, actual spacing is 40px */
}

Float vs Modern Layout ​

When Should You Use Float ​

Float still has applicable scenarios in modern development:

✅ Recommended Float Scenarios:

  1. Text wrapping images - This is float's job, most suitable scenario
css
.article-img {
  float: left;
  margin: 0 20px 15px 0;
}
  1. Occasional simple wrapping effects - Like inserting info boxes in articles

❌ Not Recommended Float Scenarios:

  1. Multi-column layout - Use Flexbox or Grid
  2. Navigation menu - Use inline-block or Flex
  3. Card grid - Use Grid
  4. Responsive layout - Use Flex or Grid

Migrating to Modern Layout ​

Float navigation → Flex navigation:

css
/* Old way: Float */
.nav li {
  float: left;
}

/* New way: Flex */
.nav {
  display: flex;
  gap: 10px;
}

Float grid → CSS Grid:

css
/* Old way: Float */
.card {
  float: left;
  width: calc(33.333% - 20px);
  margin: 10px;
}

/* New way: Grid */
.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

Float two-column layout → Flex layout:

css
/* Old way: Float */
.sidebar {
  float: left;
  width: 300px;
}
.content {
  margin-left: 340px;
}

/* New way: Flex */
.container {
  display: flex;
  gap: 40px;
}
.sidebar {
  flex: 0 0 300px;
}
.content {
  flex: 1;
}

Float Debugging Techniques ​

Visualize Float ​

Add background color and border to help understand float:

css
.container {
  background-color: #f5f5f5;
  border: 3px solid red;
}

.float-element {
  background-color: lightblue;
  border: 2px solid blue;
  float: left;
}

Use Browser Developer Tools ​

In Chrome DevTools:

  1. Select floated element
  2. Check Computed panel, confirm display has changed to block
  3. Check element's actual position and occupied space
  4. Check if parent container height has collapsed

Summary ​

Float is an early CSS layout tool, although there are better choices now, understanding float is still important.

Core Float Features:

  • Removed from document flow, but affects line boxes
  • Element automatically becomes block
  • Width shrinks to content size
  • Multiple floated elements will line up side by side
  • Will cause parent container height collapse

Float Application Scenarios:

  • ✅ Most recommended: Text wrapping images
  • âš ī¸ Can but not recommended: Multi-column layout, navigation menu, card grid
  • ❌ Not recommended: Complex responsive layout

Float Problems:

  • Height collapse (need to clear float)
  • Floated elements may misalign
  • Margins don't collapse
  • Need extra float clearing code

Modern Alternatives:

  • Multi-column layout → Flexbox or Grid
  • Navigation menu → Inline-block or Flex
  • Card grid → CSS Grid
  • Only text wrapping images recommended to continue using float

Float is like a tool "requisitioned" for layout, although it can complete work, it's not the most suitable choice. In modern development, leave float for what it's best at - text wrapping images. As for layout, leave it to Flexbox and Grid.