Float & Clear (Legacy Layout)
Introduction to CSS Floats
The CSS float property is one of the oldest layout mechanisms in CSS. Originally introduced in CSS1 back in 1996, floats were designed for a very specific purpose: allowing text to wrap around images, much like you see in printed newspapers and magazines. However, due to the lack of better layout tools for many years, web developers creatively (and sometimes painfully) used floats to build entire page layouts -- multi-column designs, navigation bars, grid-like structures, and more. Understanding floats is essential for any CSS developer because you will encounter float-based layouts in legacy codebases, and floats still serve their original purpose beautifully when you need text to flow around an element.
In this lesson, we will explore what floats do, how they affect the document flow, the problems they create, the solutions developers invented to fix those problems, and why modern layout systems like Flexbox and Grid have largely replaced float-based layouts. We will also look at cases where floats remain the best tool for the job.
What Floats Were Originally Designed For
Before CSS existed, if you wanted an image to appear with text flowing around it, you would use the HTML align attribute on the <img> tag. This mixed presentation with structure, which violated the principle of separation of concerns. CSS floats were created to provide a clean, stylesheet-based way to achieve the same effect.
The original and most natural use of floats is text wrapping around images. When you float an image to the left or right, the surrounding text reflows to fill the space beside the floated element. This mimics the behavior you see in print media, where a photograph might sit on the left side of a page while the article text wraps neatly around it.
Example: Classic Text Wrapping Around an Image
<div class="article">
<img src="photo.jpg" alt="A beautiful landscape" class="float-left">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur.</p>
</div>
CSS for Text Wrapping
.float-left {
float: left;
margin: 0 20px 10px 0;
max-width: 300px;
}
.article {
font-size: 16px;
line-height: 1.6;
}
In this example, the image is pulled to the left side of its container, and the paragraph text flows naturally around the right side of the image. The margins on the image create breathing room between the image and the text. This is exactly what floats were designed to do, and it remains one of the best use cases for the property today.
The Float Property Values
The float property accepts four values, each controlling where the element should be positioned relative to its container:
Float Property Values
/* Float the element to the left side of its container */
.element-left {
float: left;
}
/* Float the element to the right side of its container */
.element-right {
float: right;
}
/* Remove any float from the element (default value) */
.element-none {
float: none;
}
/* Float to the start of the inline direction (logical property) */
.element-start {
float: inline-start;
}
/* Float to the end of the inline direction (logical property) */
.element-end {
float: inline-end;
}
float: left
When you apply float: left to an element, the element is taken out of the normal document flow and pushed to the left edge of its containing block. Any content that follows the floated element will flow around its right side. Multiple left-floated elements will stack horizontally from left to right, wrapping to the next line if there is not enough horizontal space.
float: right
The float: right value works identically to float: left but in the opposite direction. The element is pushed to the right edge of its containing block, and subsequent content flows around its left side. Multiple right-floated elements stack from right to left.
float: none
The value float: none is the default. It means the element is not floated and participates in the normal document flow as usual. You might use this value to override a float that was set by a more general rule or in a media query to remove floats at certain screen sizes.
inline-start and inline-end values are logical properties that respect the writing direction. In a left-to-right language, inline-start behaves like left, while in a right-to-left language like Arabic, inline-start behaves like right. These values have good browser support in modern browsers.How Floats Remove Elements from Normal Flow
One of the most important concepts to understand about floats is that a floated element is removed from the normal document flow. This is what makes floats powerful, but also what makes them tricky and error-prone.
In the normal document flow, block-level elements stack vertically one on top of another, and inline elements flow horizontally within their parent. When you float an element, it is lifted out of this normal stacking order. The floated element still takes up space visually -- text and inline elements will wrap around it -- but block-level elements behind the float act as if the floated element does not exist.
Example: Float Removing Element from Flow
<div class="container">
<div class="box floated">I am floated left</div>
<div class="box normal">I am a normal block element. My background
extends behind the floated element because I do not "see" it in the
normal flow. However, my text content wraps around the float.</div>
</div>
CSS Demonstrating Flow Behavior
.floated {
float: left;
width: 150px;
height: 150px;
background: #3498db;
color: white;
padding: 10px;
}
.normal {
background: #e74c3c;
color: white;
padding: 10px;
}
In this example, the red .normal box will stretch the full width of the container. Its background will extend behind the blue floated box because the float is out of normal flow. However, the text inside the .normal box will wrap around the float. This dual behavior -- block box ignoring the float, text content respecting the float -- is one of the most confusing aspects of floats for beginners.
<span>, it will behave as a block element and accept width, height, vertical margin, and vertical padding. The computed value of display changes to block (or the appropriate block-level equivalent).The Clear Property
The clear property is the companion to float. It is used on elements that should NOT wrap around floated elements. When you apply clear to an element, you are telling the browser: "This element should be placed below any preceding floats, not beside them."
Clear Property Values
/* Do not allow floated elements on the left side */
.clear-left {
clear: left;
}
/* Do not allow floated elements on the right side */
.clear-right {
clear: right;
}
/* Do not allow floated elements on either side */
.clear-both {
clear: both;
}
/* Default -- allows floated elements on both sides */
.clear-none {
clear: none;
}
clear: left
The element is moved below any preceding left-floated elements. It will only clear left floats, so right-floated elements can still appear beside it.
clear: right
The element is moved below any preceding right-floated elements. Left-floated elements can still appear beside it.
clear: both
This is the most commonly used value. The element is moved below any preceding floated elements, regardless of whether they are floated left or right. This is the safest choice when you want to ensure an element starts on a completely new line below all floats.
Example: Using Clear to Create Sections
<div class="container">
<img src="photo1.jpg" class="float-left">
<p>This text wraps around the image on the right side.</p>
<div class="clear-both"></div>
<img src="photo2.jpg" class="float-right">
<p>This text wraps around the second image on the left side.</p>
</div>
CSS for the Clear Example
.float-left {
float: left;
margin: 0 15px 10px 0;
max-width: 250px;
}
.float-right {
float: right;
margin: 0 0 10px 15px;
max-width: 250px;
}
.clear-both {
clear: both;
}
The empty div with clear: both acts as a divider. Everything after it starts fresh, below all previous floats. While using an empty element for clearing is considered a hack (we will see better solutions soon), it illustrates how the clear property works.
The Parent Collapse Problem
The most infamous problem with CSS floats is parent collapse. When all children of a container are floated, the container collapses to zero height because it has no in-flow content to determine its height. The parent element effectively "forgets" that it has children.
Example: Parent Collapse
<div class="parent">
<div class="child" style="float: left; width: 50%;">Column 1</div>
<div class="child" style="float: left; width: 50%;">Column 2</div>
</div>
<p>This paragraph appears right after the parent div.</p>
CSS Showing the Problem
.parent {
background: #f0f0f0;
border: 2px solid #333;
padding: 10px;
/* This parent will have zero height! */
}
.child {
background: #3498db;
color: white;
padding: 20px;
box-sizing: border-box;
}
In this example, the .parent div will have a height of zero (plus its padding). The background color and border will not wrap around the floated children. The paragraph that follows will slide up right underneath the floated elements, overlapping them. This is a direct consequence of floats being removed from the normal flow.
The Clearfix Hack and Its Evolution
The parent collapse problem was so common and so frustrating that the CSS community invented a technique known as the clearfix hack. This technique forces a parent container to acknowledge its floated children and expand to contain them. The clearfix evolved through several iterations over the years.
Solution 1: The Empty Div Method (Earliest)
The simplest (and dirtiest) solution was to add an empty element at the end of the container with clear: both:
Empty Div Clearfix
<div class="parent">
<div class="child" style="float: left;">Column 1</div>
<div class="child" style="float: left;">Column 2</div>
<div style="clear: both;"></div>
</div>
This works, but it adds meaningless HTML to the document. It violates the principle of separation of concerns because you are adding structural elements purely for visual purposes.
Solution 2: The overflow Method
Setting overflow: hidden or overflow: auto on the parent creates a new Block Formatting Context (BFC), which forces the parent to contain its floated children:
Overflow Clearfix
.parent {
overflow: hidden; /* or overflow: auto */
background: #f0f0f0;
border: 2px solid #333;
}
This is cleaner because it requires no extra HTML. However, it has a side effect: any content that overflows the container will be hidden (with overflow: hidden) or will trigger scrollbars (with overflow: auto). This makes it unsuitable in situations where you need content to overflow, such as dropdown menus or tooltips that extend beyond their parent.
Solution 3: The Micro Clearfix (Most Popular)
The micro clearfix, popularized by Nicolas Gallagher, uses the ::after pseudo-element to insert a clearing element without any extra HTML:
Micro Clearfix (Classic Version)
/* The classic micro clearfix */
.clearfix::before,
.clearfix::after {
content: "";
display: table;
}
.clearfix::after {
clear: both;
}
/* For IE 6/7 support (rarely needed today) */
.clearfix {
*zoom: 1;
}
This technique generates invisible pseudo-elements before and after the container's content. The ::after pseudo-element has clear: both, which forces the parent to extend past all floated children. The display: table creates a new BFC and prevents margin collapsing. The ::before pseudo-element prevents top-margin collapse of the first child.
Using the Clearfix
<div class="parent clearfix">
<div class="child" style="float: left; width: 50%;">Column 1</div>
<div class="child" style="float: left; width: 50%;">Column 2</div>
</div>
<!-- Now the parent properly wraps its children -->
Solution 4: display: flow-root (Modern Standard)
The modern and cleanest solution is display: flow-root. This CSS property was specifically designed to solve the parent collapse problem. It creates a new Block Formatting Context without any side effects:
Modern Clearfix with display: flow-root
.parent {
display: flow-root;
background: #f0f0f0;
border: 2px solid #333;
padding: 10px;
}
With display: flow-root, the parent automatically contains its floated children. There is no need for clearfix hacks, no overflow issues, and no extra HTML. The element still behaves like a block-level element in every other way. This is the recommended approach for any project that does not need to support very old browsers.
display: flow-root has been supported in all major browsers since 2017 (Chrome 58, Firefox 53, Safari 13, Edge 79). Unless you need to support Internet Explorer, you should use display: flow-root instead of any clearfix hack.Float-Based Layouts (Historical Context)
Before Flexbox (2012) and CSS Grid (2017) were widely supported, floats were the primary tool for creating multi-column page layouts. Developers used floats to position sidebars, create column grids, build navigation bars, and structure entire page templates. This was never what floats were designed for, and it required numerous workarounds and hacks.
Two-Column Layout with Floats
Example: Float-Based Two-Column Layout
<div class="page-layout clearfix">
<main class="main-content">
<h1>Main Content Area</h1>
<p>This is the primary content of the page...</p>
</main>
<aside class="sidebar">
<h2>Sidebar</h2>
<ul>
<li>Link 1</li>
<li>Link 2</li>
<li>Link 3</li>
</ul>
</aside>
</div>
CSS for Two-Column Float Layout
.page-layout {
max-width: 1200px;
margin: 0 auto;
}
.main-content {
float: left;
width: 70%;
padding-right: 30px;
box-sizing: border-box;
}
.sidebar {
float: right;
width: 30%;
padding-left: 20px;
box-sizing: border-box;
}
/* Clearfix for the layout container */
.clearfix::after {
content: "";
display: table;
clear: both;
}
Three-Column Layout with Floats
Three-Column Float Layout
.left-sidebar {
float: left;
width: 20%;
}
.main-content {
float: left;
width: 60%;
padding: 0 20px;
box-sizing: border-box;
}
.right-sidebar {
float: right;
width: 20%;
}
Horizontal Navigation with Floats
Float-Based Navigation
<nav class="main-nav clearfix">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/services">Services</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
CSS for Float-Based Navigation
.main-nav ul {
list-style: none;
margin: 0;
padding: 0;
}
.main-nav li {
float: left;
}
.main-nav a {
display: block;
padding: 10px 20px;
color: white;
background: #2c3e50;
text-decoration: none;
}
.main-nav a:hover {
background: #34495e;
}
Problems with Float Layouts
While float-based layouts technically work, they came with significant problems that made them painful to maintain:
- Equal-height columns were impossible -- Floated columns are independent of each other. If the main content was 500px tall and the sidebar was 200px tall, the sidebar would be shorter. Developers used hacks like faux columns (background images) or JavaScript to simulate equal heights.
- Vertical centering was extremely difficult -- Floats provide no mechanism for vertically centering content. Developers resorted to padding tricks, line-height hacks, or table-cell display.
- Source order was tied to visual order -- The order elements appeared in HTML had to match (roughly) their visual position on the page. Rearranging the layout for different screen sizes required different HTML structures or complex float/clear combinations.
- Fragile layouts -- Adding a few pixels of padding or border could break the entire layout because percentage-based widths did not account for padding and borders (before
box-sizing: border-boxbecame standard). - Clearfix requirements -- Every container with floated children needed a clearfix, adding complexity and potential for bugs.
- No gap control -- There was no built-in way to add consistent gaps between floated columns. Developers used margins and padding, which required careful calculation.
Why Flexbox and Grid Replaced Float Layouts
Flexbox and CSS Grid solve every problem that float layouts had, plus they provide capabilities that were simply impossible with floats:
Comparison: Float Layout vs Flexbox
/* Float-based two columns (fragile) */
.container-float {
overflow: hidden; /* clearfix */
}
.container-float .main {
float: left;
width: 70%;
padding-right: 20px;
box-sizing: border-box;
}
.container-float .sidebar {
float: right;
width: 30%;
}
/* Flexbox two columns (robust) */
.container-flex {
display: flex;
gap: 20px;
}
.container-flex .main {
flex: 7;
}
.container-flex .sidebar {
flex: 3;
}
The Flexbox version is shorter, more readable, automatically creates equal-height columns, handles gaps natively, and is far less likely to break when content changes. CSS Grid takes this even further with full two-dimensional control.
When Floats Are Still Useful Today
Despite being replaced for layout purposes, floats remain relevant and useful in specific scenarios:
1. Text Wrapping Around Images
This is the original and still best use case for floats. When you have an article with inline images and you want the text to flow naturally around them, floats are the correct tool.
Article with Wrapped Images
.article-image-left {
float: left;
margin: 0 20px 15px 0;
max-width: 40%;
border-radius: 8px;
}
.article-image-right {
float: right;
margin: 0 0 15px 20px;
max-width: 40%;
border-radius: 8px;
}
2. Drop Caps
Floating the first letter of a paragraph to create a decorative drop cap effect:
Drop Cap with Float
.article p::first-letter {
float: left;
font-size: 3.5em;
line-height: 0.8;
padding: 4px 8px 0 0;
font-weight: bold;
color: #2c3e50;
font-family: Georgia, serif;
}
3. Pull Quotes
Creating pull quotes that sit within the flow of text, with the article text wrapping around them:
Pull Quote with Float
.pull-quote {
float: right;
width: 40%;
margin: 0 0 15px 25px;
padding: 15px 20px;
border-left: 4px solid #3498db;
font-size: 1.3em;
font-style: italic;
color: #555;
}
shape-outside: Creative Text Wrapping
The shape-outside property is a modern CSS feature that works exclusively with floated elements. It allows you to define a custom shape that text will wrap around, rather than wrapping around the rectangular bounding box of the float. This enables beautiful, magazine-quality text layouts that were previously impossible with CSS alone.
shape-outside with Basic Shapes
/* Circular text wrapping */
.circular-image {
float: left;
width: 200px;
height: 200px;
border-radius: 50%;
shape-outside: circle(50%);
margin: 0 20px 10px 0;
}
/* Elliptical text wrapping */
.ellipse-wrap {
float: left;
width: 200px;
height: 300px;
shape-outside: ellipse(50% 50%);
clip-path: ellipse(50% 50%);
margin-right: 15px;
}
/* Polygon text wrapping */
.diamond-wrap {
float: left;
width: 200px;
height: 200px;
shape-outside: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
margin-right: 15px;
}
/* Inset (rounded rectangle) */
.rounded-wrap {
float: left;
width: 200px;
height: 200px;
shape-outside: inset(0 round 20px);
margin-right: 15px;
}
shape-outside with Images
One of the most powerful uses of shape-outside is with images that have transparency. The browser can detect the shape of the non-transparent pixels in an image and wrap text around the actual shape of the content:
shape-outside with Image Alpha Channel
/* Text wraps around the actual shape of the PNG */
.shaped-image {
float: left;
width: 250px;
shape-outside: url('transparent-shape.png');
shape-margin: 15px;
shape-image-threshold: 0.5;
}
/* shape-margin adds space between the shape and the text */
/* shape-image-threshold determines the alpha level
that defines the shape boundary (0 to 1) */
shape-outside only affects how text wraps around a float. It does not change the visual shape of the element itself. To make the element visually match the shape, combine shape-outside with clip-path using the same shape value. This creates a cohesive visual effect where the element looks shaped and the text follows that shape.Practical Example: Magazine-Style Article Layout
Let us build a complete magazine-style article layout that uses floats for their intended purpose -- text wrapping -- combined with modern techniques for the overall structure:
HTML Structure
<article class="magazine-article">
<h1>The Art of Mountain Photography</h1>
<img src="hero-mountain.jpg" alt="Mountain landscape"
class="article-hero-image">
<p class="intro">Mountain photography requires patience, skill, and a deep
appreciation for the ever-changing moods of nature. In this guide, we explore
the techniques that professional photographers use to capture breathtaking
alpine scenery.</p>
<h2>Finding the Perfect Light</h2>
<img src="golden-hour.jpg" alt="Golden hour in the mountains"
class="float-left rounded">
<p>The golden hour -- that magical period just after sunrise or just before
sunset -- is when mountains truly come alive with color. The low angle of
the sun creates dramatic shadows that emphasize the rugged texture of rock
faces and ridgelines. Colors shift from warm oranges and reds to cool blues
and purples as the sun moves across the sky.</p>
<p>Many photographers set their alarms for well before dawn, hiking in
darkness to reach their shooting position before first light. The effort is
always worthwhile when that first ray of sunlight hits a snow-capped peak
and paints it in shades of gold and pink.</p>
<blockquote class="pull-quote-right">
“The mountain does not care about your camera settings. It cares
only that you were there to witness the light.”
</blockquote>
<p>Cloud formations add another layer of drama to mountain photography.
Lenticular clouds, which form over peaks due to wind patterns, create
otherworldly scenes that can transform an ordinary photograph into something
extraordinary.</p>
</article>
CSS for Magazine Layout
.magazine-article {
max-width: 800px;
margin: 0 auto;
font-family: Georgia, 'Times New Roman', serif;
font-size: 18px;
line-height: 1.8;
color: #333;
}
.magazine-article h1 {
font-size: 2.5em;
line-height: 1.2;
margin-bottom: 20px;
}
.article-hero-image {
width: 100%;
height: auto;
margin-bottom: 25px;
border-radius: 4px;
}
.magazine-article .intro {
font-size: 1.15em;
color: #555;
border-left: 3px solid #3498db;
padding-left: 20px;
margin-bottom: 30px;
}
/* Float-based text wrapping */
.float-left {
float: left;
max-width: 45%;
margin: 5px 25px 15px 0;
}
.float-left.rounded {
border-radius: 8px;
shape-outside: inset(0 round 8px);
}
/* Pull quote using float */
.pull-quote-right {
float: right;
width: 35%;
margin: 5px 0 15px 30px;
padding: 15px;
border-right: 4px solid #e74c3c;
font-size: 1.2em;
font-style: italic;
color: #666;
line-height: 1.5;
}
/* Ensure article contains all floats */
.magazine-article {
display: flow-root;
}
Practical Example: Float-Based Image Gallery
While you would use CSS Grid or Flexbox for image galleries today, understanding the float-based approach helps you maintain legacy code:
Float-Based Image Gallery
<div class="gallery clearfix">
<div class="gallery-item">
<img src="photo1.jpg" alt="Photo 1">
<p>Mountain Sunrise</p>
</div>
<div class="gallery-item">
<img src="photo2.jpg" alt="Photo 2">
<p>Forest Trail</p>
</div>
<div class="gallery-item">
<img src="photo3.jpg" alt="Photo 3">
<p>Lake Reflection</p>
</div>
<div class="gallery-item">
<img src="photo4.jpg" alt="Photo 4">
<p>Snowy Peak</p>
</div>
</div>
CSS for Float Gallery
.gallery {
max-width: 1000px;
margin: 0 auto;
}
.gallery-item {
float: left;
width: 25%;
padding: 10px;
box-sizing: border-box;
text-align: center;
}
.gallery-item img {
width: 100%;
height: auto;
border-radius: 4px;
}
.gallery-item p {
margin-top: 8px;
font-size: 14px;
color: #555;
}
/* Responsive: 2 columns on tablets */
@media (max-width: 768px) {
.gallery-item {
width: 50%;
}
}
/* Responsive: 1 column on phones */
@media (max-width: 480px) {
.gallery-item {
width: 100%;
float: none;
}
}
/* Clearfix */
.clearfix::after {
content: "";
display: table;
clear: both;
}
shape-outside: circle() on the featured image if it is circular. Apply display: flow-root on the container instead of a clearfix hack. Test that the layout does not break when the text is shorter than the image.shape-outside on at least two images to create non-rectangular text wrapping. Add a caption paragraph below the gallery that clears all floats. Make the gallery responsive: 3 columns on desktop, 2 on tablet, and 1 on mobile.Summary
CSS floats were a groundbreaking feature when they were introduced, enabling text to wrap around elements and, for many years, serving as the primary tool for page layouts. However, floats were never designed for complex layouts, and the hacks required to make them work reliably (clearfix, overflow tricks, careful width calculations) made float-based layouts fragile and difficult to maintain. Today, Flexbox and CSS Grid provide far superior layout capabilities, but floats remain the best choice for their original purpose: wrapping text around images and other inline content. Understanding floats is essential for maintaining legacy code and for leveraging features like shape-outside that only work with floated elements.