CSS floats were once the primary tool for building multi-column layouts, and while Flexbox and Grid have replaced them for layout work, floats remain relevant for one thing they do uniquely well: wrapping text around images. Every frontend developer encounters float-based legacy code and needs to understand how floats work and how to clear them properly. In this lesson you will learn float mechanics, clearing techniques, and when a float is still the right tool.
Float Mechanics
| Concept | Description | Example Effect |
|---|---|---|
float: left |
Element shifts to the left edge; text and inline content wraps to its right | Image on left, article text flowing right |
float: right |
Element shifts to the right edge; content wraps to its left | Pull-quote on right side of article |
float: none |
Default โ no floating | Element in normal flow |
| Out of flow | Floated elements are partially removed from document flow | Parent container collapses to 0 height |
| Inline content wraps | Text and inline elements respect floated elements | Block siblings do NOT wrap โ they slide under |
Clearing Techniques
| Technique | How | When to Use |
|---|---|---|
clear: both |
On a sibling element โ it drops below all floats | Force next section below floats |
| Clearfix hack | ::after pseudo-element with content:"", display:table, clear:both |
Make parent contain its floated children |
overflow: hidden/auto |
On parent โ creates a Block Formatting Context (BFC) | Simple containment where overflow side-effect is acceptable |
display: flow-root |
On parent โ creates BFC with no side effects | Modern clearfix; best practice today |
Float Still Useful vs Better Alternatives
| Task | Use Float? | Better Alternative |
|---|---|---|
| Text wrapping around an image | Yes โ float is the only CSS tool for this | N/A โ float is correct here |
| Multi-column layout | No โ legacy pattern | Flexbox or CSS Grid |
| Sidebar + main layout | No โ legacy pattern | Flexbox or CSS Grid |
| Drop caps | Possible โ but pseudo-element is cleaner | p::first-letter { float: left; } |
display: flow-root to the container is the modern solution โ it creates a Block Formatting Context that causes the parent to contain its floated children without any side effects.display: flow-root is the modern replacement for the old clearfix hack. Unlike overflow: hidden, it does not clip content; unlike overflow: auto, it does not add scrollbars. It simply establishes a BFC that contains floats โ use it whenever you need to clear floats on a parent.float for page layout in new projects. Floats introduce fragile clearing dependencies and parent collapse issues that Flexbox and Grid solve inherently. If you inherit float-based code, refactor section by section rather than patching with more floats.Basic Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Float and Clear</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { font-family: Georgia, 'Times New Roman', serif; padding: 40px; background: #fafaf9; color: #1c1917; max-width: 700px; margin: 0 auto; line-height: 1.75; }
h2 { font-family: system-ui, sans-serif; margin: 32px 0 16px; font-size: 1.1rem; }
/* โโ Standard text wrap around image โโ */
.article-section { display: flow-root; } /* contains floated image */
.float-img {
float: left;
width: 220px;
height: 160px;
background: linear-gradient(135deg, #4f46e5, #7c3aed);
border-radius: 10px;
margin: 0 20px 12px 0;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-family: system-ui, sans-serif;
font-size: 0.8rem;
font-weight: 600;
flex-shrink: 0;
}
.float-img-right {
float: right;
width: 180px;
height: 130px;
background: linear-gradient(135deg, #0891b2, #0284c7);
border-radius: 10px;
margin: 0 0 12px 20px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-family: system-ui, sans-serif;
font-size: 0.8rem;
font-weight: 600;
}
/* โโ clear: both forces element below all floats โโ */
.clear-section {
clear: both;
margin-top: 24px;
padding: 16px 20px;
background: #f0fdf4;
border-left: 4px solid #10b981;
border-radius: 0 8px 8px 0;
font-family: system-ui, sans-serif;
font-size: 0.875rem;
}
/* โโ Drop cap via float โโ */
.drop-cap-para::first-letter {
float: left;
font-size: 4rem;
line-height: 0.8;
font-weight: 700;
color: #4f46e5;
margin: 4px 8px 0 0;
font-family: Georgia, serif;
}
</style>
</head>
<body>
<h2>Float left โ text wraps to the right</h2>
<div class="article-section">
<div class="float-img">float: left</div>
<p>This paragraph text flows around the floated image on the left. The browser places the floated element at the left edge of its container, then wraps inline content โ text in this case โ around its right side. Notice how the text stays on the right of the image until it clears the image's bottom edge, then returns to the full container width.</p>
<p>A second paragraph continues wrapping. The parent <code>div</code> has <code>display: flow-root</code> which causes it to contain the floated image instead of collapsing to zero height.</p>
</div>
<h2>Float right โ text wraps to the left</h2>
<div class="article-section">
<div class="float-img-right">float: right</div>
<p>Here the image is floated to the right, and text wraps to its left. This is the classic pull-quote or aside pattern in editorial layouts. The containing div again uses display: flow-root to contain the float.</p>
</div>
<div class="clear-section">clear: both โ this element starts below all floats above it</div>
<h2>Drop cap using float</h2>
<p class="drop-cap-para">Floats are still the correct tool for drop-cap letter effects where the oversized first letter should have text wrapping around its bottom-right. The ::first-letter pseudo-element combined with float: left creates this editorial typographic effect cleanly and without JavaScript.</p>
</body>
</html>
How It Works
Step 1 โ float: left Shifts Element and Wraps Text
The floated image moves to the left edge of its containing block. Text content โ being inline โ detects the float and flows to its right. Block-level siblings (other divs, paragraphs) slide underneath the float but their inline text content wraps around it.
Step 2 โ display: flow-root Contains the Float
Without display: flow-root on the parent, the parent container would collapse to zero height because the floated element is partially out of flow. flow-root creates a Block Formatting Context โ a formatting scope that must contain its floated descendants.
Step 3 โ clear: both Forces Element Below Floats
The clearfix div has clear: both which means “do not sit beside any float โ drop below all left and right floats that precede me.” This is used to ensure a following section always starts below any preceding floats.
Step 4 โ Drop Cap Uses ::first-letter + float
p::first-letter { float: left; font-size: 4rem; } selects only the first letter of the paragraph, enlarges it, and floats it left so the remaining text wraps around its bottom-right. This is the one legitimate modern use of float for purely typographic effect.
Step 5 โ Block Siblings Do Not Wrap Around Floats
Block-level elements (divs, sections) do not visually avoid floats โ they slide underneath them. Only their inline content (text, images) wraps. This subtle distinction explains why float-based column layouts require careful clearing โ without it, subsequent block elements overlap the floated columns.
Real-World Example: Article with Inline Image and Pull Quote
/* editorial.css */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: Georgia, serif;
color: #1c1917;
max-width: 680px;
margin: 0 auto;
padding: 48px 24px;
line-height: 1.8;
font-size: 1.05rem;
background: #fffbf7;
}
h1 { font-size: 2rem; line-height: 1.2; margin-bottom: 8px; }
p { margin-bottom: 20px; }
/* Article section containing floats */
.article-body { display: flow-root; }
/* Inline image โ floated left */
.article-img {
float: left;
width: 260px;
height: 200px;
object-fit: cover;
border-radius: 10px;
margin: 4px 24px 16px 0;
display: block;
}
/* Pull quote โ floated right */
.pull-quote {
float: right;
width: 200px;
margin: 4px 0 16px 24px;
padding: 16px 20px;
background: #fef9c3;
border-left: 4px solid #eab308;
border-radius: 0 8px 8px 0;
font-style: italic;
font-size: 1rem;
line-height: 1.5;
color: #78350f;
}
/* After floated content, clear before next section */
.section-break {
clear: both;
display: block;
height: 1px;
background: #e7e5e4;
margin: 32px 0;
}
Common Mistakes
Mistake 1 โ Parent collapses because of floated children
โ Wrong โ container height collapses to zero; background/border disappears:
.container { background: #f0f9ff; }
.child { float: left; width: 50%; }
/* .container renders as 0px tall โ background not visible */
โ Correct โ add display: flow-root to the container:
.container { background: #f0f9ff; display: flow-root; }
.child { float: left; width: 50%; }
Mistake 2 โ Using float for layout instead of Flexbox/Grid
โ Wrong โ brittle float-based two-column layout:
.sidebar { float: left; width: 30%; }
.main { float: left; width: 70%; }
.footer { clear: both; }
โ Correct โ use Flexbox for maintainable two-column layout:
.layout { display: flex; gap: 24px; }
.sidebar { flex: 0 0 30%; }
.main { flex: 1; }
Mistake 3 โ Missing clear after float-based columns
โ Wrong โ footer overlaps floated columns:
.col { float: left; width: 50%; }
.footer { /* no clear โ overlaps columns */ }
โ Correct โ clear before the footer:
.col { float: left; width: 50%; }
.footer { clear: both; }
Quick Reference
| Property / Value | Effect | Notes |
|---|---|---|
float: left |
Shifts to left; inline content wraps right | Still valid for text-wrap-around-image |
float: right |
Shifts to right; inline content wraps left | Pull quotes, editorial asides |
clear: both |
Forces element below all preceding floats | On sibling after float group |
display: flow-root |
Contains floated children; no side effects | Modern clearfix โ use on parent |
overflow: hidden |
Also contains floats (creates BFC) | Side effect: clips overflowing content |
| Legacy clearfix | ::after { content:""; display:table; clear:both; } |
Use flow-root instead in new code |