Question
Containing Floated Elements in CSS: Clearfix and Modern Solutions
Question
When child elements are floated, their non-floated parent can appear to collapse to height: 0 rather than expanding around them.
<div class="parent">
<div class="item">Div 1</div>
<div class="item">Div 2</div>
</div>
.item {
float: left;
}
Why does this happen, and what are the correct ways to make the parent contain its floated children? What are the trade-offs and browser considerations for approaches such as floating the parent, setting a fixed height, adding a clearing element, using overflow, or using clearfix?
Short Answer
You will learn why float removes elements from normal document flow, why that affects a parent’s height, and how to contain floats safely. You will also see the modern display: flow-root solution, the classic clearfix pattern, and why Flexbox or Grid is usually better for new layouts.
Concept
A floated element is taken out of normal flow. It still displays and affects nearby inline content, but it no longer contributes to the height calculation of a normal block parent.
That is why this parent has no visible height when all of its children float:
.parent {
border: 2px solid tomato;
}
.item {
float: left;
}
The border may appear as a line with zero height, even though the floated items are visible.
This matters because a collapsed parent can cause later content to move upward beside the floats, backgrounds and borders to disappear around the children, and spacing between page sections to break.
Floats were originally designed to let text wrap around content such as images. They were later widely used for columns and navigation layouts. Modern CSS provides Flexbox and Grid for most new layout work, but float containment remains important when maintaining older stylesheets or when using floats for their intended text-wrapping behavior.
The preferred modern way to make a parent contain its floats is:
.parent {
display: flow-root;
}
This creates a new block formatting context, causing the parent to include its floated descendants in its height.
Mental Model
Think of normal-flow elements as books placed on a shelf: each book takes up space, so the shelf must be tall enough to hold them.
A floated element is more like a note pinned beside the shelf. It remains visible, but the shelf does not count it when measuring its own height. If every child is pinned beside the shelf, the shelf appears empty.
A float-containment technique tells the parent: “Measure the floated items too.” A clearing element acts like a final normal-flow object that must sit below the floats. display: flow-root creates a self-contained area that measures its internal floats correctly.
Syntax and Examples
The modern float-containment syntax is display: flow-root.
<div class="card-list">
<article class="card">First card</article>
<article class="card">Second card</article>
</div>
.card-list {
display: flow-root;
border: 2px solid #555;
padding: 12px;
}
.card {
float: left;
width: 140px;
margin-right: 12px;
padding: 16px;
background: #dbeafe;
}
.card-list now grows tall enough to surround both floated .card elements.
Classic clearfix
If you need to support environments where flow-root cannot be used, apply a clearfix utility class to the parent:
.clearfix::after {
content: "";
display: table;
clear: both;
}
<div class="card-list clearfix">
<article class="card">First card</article>
<article class="card">Second card</article>
</div>
The generated ::after pseudo-element is in normal flow and clears both left and right floats, so it forces the parent to extend below them.
Clearing following content
Sometimes you do not need the parent itself to contain floats. You may instead need the next section to start below them:
.next-section {
clear: both;
}
Use this only when clearing the following sibling is actually the desired layout behavior.
Step by Step Execution
Consider this code:
<div class="parent">
<div class="box">A</div>
<div class="box">B</div>
</div>
<p>Content after the parent.</p>
.parent {
border: 3px solid seagreen;
}
.box {
float: left;
width: 80px;
height: 50px;
margin: 4px;
background: gold;
}
Execution in layout terms:
- The browser creates the
.parentblock in normal flow. - Each
.boxis floated left, so it is removed from normal-flow height calculations. .parenthas no normal-flow content, no explicit height, and no relevant padding, so its computed content height is effectively zero.- The gold boxes remain visible, but they extend outside the visual height of the green border.
- The paragraph can flow alongside the floats if there is room.
Now add this rule:
.parent {
display: flow-root;
}
The parent establishes a new block formatting context. Its layout now accounts for its internal floats, so the border expands around the two boxes and the paragraph begins below the parent.
Real World Use Cases
Float containment still appears in practical situations such as:
- Article images: Float an image left or right so paragraph text wraps around it, while keeping the article section’s background and border around the image.
- Legacy navigation bars: Older sites may use floated list items for horizontal navigation and need the navigation container to have a height.
- Maintaining existing themes: CMS templates, older component libraries, and email-like HTML layouts may contain float-based styles that cannot be rewritten immediately.
- Rich-text content: User-authored HTML may include floated images. A wrapper using
flow-rootcan prevent the surrounding content block from collapsing. - Scoped utility classes: A reusable
.clearfixclass can repair old float-based components without changing their markup structure.
Real Codebase Usage
For a new row of cards, buttons, or columns, developers usually choose Flexbox or Grid instead of floats:
.card-list {
display: flex;
gap: 12px;
}
But when a float is necessary, codebases commonly use one of these patterns.
Prefer a local containment rule
.article-body {
display: flow-root;
}
.article-body img.align-left {
float: left;
margin: 0 16px 8px 0;
}
This keeps the behavior close to the component that needs it.
Reusable clearfix utility for legacy CSS
.u-clearfix::after {
content: "";
display: block;
clear: both;
}
<section class="legacy-panel u-clearfix">
<div class="legacy-column">...</div>
<div class="legacy-column">...</div>
</section>
Avoid using overflow solely as a default clearfix
overflow: auto or overflow: hidden can establish a formatting context and contain floats, but it also controls clipping and scrolling. It is appropriate only when those overflow effects are intentional:
.image-frame {
overflow: hidden;
}
For example, a frame may intentionally crop an oversized image. In that case, float containment is a side effect, not the reason for choosing overflow.
Common Mistakes
Setting an arbitrary fixed height
/* Fragile: breaks if content grows. */
.parent {
height: 300px;
}
A fixed height can create empty space, overflow, or clipped content when text wraps differently on smaller screens. Use display: flow-root or clearfix when the height should follow content.
Adding an empty element without clearing it
<div class="parent">
<div class="box">A</div>
<div class="box">B</div>
<div></div>
</div>
An empty normal element alone does not necessarily solve the issue. It must clear the floats:
<div class="clear"></div>
.clear {
clear: both;
}
Prefer a pseudo-element clearfix or flow-root so presentation-only markup is not needed.
Using overflow: hidden without considering clipping
.parent {
overflow: hidden;
}
This can cut off shadows, dropdown menus, focus outlines, or intentionally overflowing content. Do not use it only because it happens to contain floats.
Floating every ancestor
Floating the parent can make it contain internal floats, but it also removes the parent from normal flow. That often causes the same issue one level higher and changes its width behavior. Do not float ancestors merely to repair float containment.
Using clear on the floated children
clear controls how an element positions itself relative to earlier floats; it does not directly make its parent calculate height. Apply containment to the parent or add a clearing item after the final float.
Using floats for a modern column layout
Floats do not provide the alignment, gap, wrapping, ordering, and responsive controls that Flexbox and Grid provide. Use them primarily for text wrapping or legacy maintenance.
Comparisons
| Approach | Contains floated children? | Best use | Main drawback |
|---|---|---|---|
display: flow-root | Yes | Modern float containment | Not needed if you can remove floats entirely |
| Clearfix pseudo-element | Yes | Legacy styles and reusable utility classes | Adds a CSS workaround for an older layout model |
| Empty clearing element | Yes | Rare cases where markup is unavoidable | Non-semantic, presentation-only markup |
overflow: auto / hidden | Usually | When overflow behavior is also intended | May add scrollbars or clip content |
Fixed height | Only at one known size | Truly fixed-size components | Fails for dynamic content |
| Float the parent | Often | Special float-based layouts | Parent is removed from normal flow too |
| Flexbox / Grid | Not applicable; avoids float issue | New rows, columns, and page layouts | Does not replicate text wrapping around a float |
flow-root versus clearfix
Both solve the containment problem. Choose display: flow-root when you control the parent’s CSS and want a direct, readable declaration. Choose clearfix when maintaining a project that already uses the utility pattern or needs to avoid changing the parent’s display behavior.
Floats versus Flexbox
Use a float when content should wrap around an item, such as an image inside an article. Use Flexbox for a one-dimensional row or column of UI elements. Use Grid when both rows and columns need deliberate control.
Cheat Sheet
/* Preferred modern float containment */
.parent {
display: flow-root;
}
/* Classic clearfix utility */
.clearfix::after {
content: "";
display: table;
clear: both;
}
/* Clear a following element, not the parent */
.after-floats {
clear: both;
}
/* Use only when clipping or scrolling is desired too */
.parent {
overflow: auto;
}
- Floated children do not contribute to the normal-flow height of their parent.
clear: bothmeans “start below earlier left and right floats.”- Avoid arbitrary fixed heights for content that can change.
- Avoid empty spacer elements when a pseudo-element can do the same job.
- For new UI layouts, prefer
display: flexordisplay: gridover floats. overflow: hiddencan contain floats but may clip shadows, menus, and focus indicators.
FAQ
Why does a parent div collapse when its children are floated?
Because float removes children from normal document flow. A normal parent calculates its automatic height from normal-flow children, so floated children are not counted.
What is the best modern way to contain floats?
Use display: flow-root on the parent when you need to keep floats. It explicitly creates a formatting context that contains the floats.
Is clearfix still useful?
Yes. Clearfix is useful in legacy codebases and as a reusable compatibility pattern. For new code that uses floats, display: flow-root is usually clearer.
Does overflow: auto fix collapsed float parents?
Usually, yes, because it creates a formatting context. However, it can create scrollbars when content overflows, so use it only if that behavior is acceptable.
Why is overflow: hidden risky as a clearfix?
It may hide content that extends beyond the parent, including box shadows, dropdowns, tooltips, and keyboard focus outlines.
Should I set a height on the parent?
Only if the component genuinely has a fixed, known height. Do not use a fixed height just to make a parent include dynamic floated content.
Should I use floats for columns in a new website?
Usually no. Flexbox and Grid are designed for modern page and component layouts. Floats are primarily useful for wrapping text around an element.
Does clear: both belong on the parent?
Usually no. Put float containment on the parent with flow-root or clearfix. clear is typically used on an element after the floats.
Mini Project
Description
Build a small article section with a floated thumbnail image and wrapped text. The section needs a visible border and background that continue around both the image and the text, demonstrating safe float containment.
Goal
Create an article preview whose parent expands around a floated image without using a fixed height or an empty spacer element.
Requirements
Use a floated image or image-like element on the left.
Add multiple paragraphs of text that wrap beside the floated element.
Give the article container a border, padding, and background color.
Make the article container contain its floated child with display: flow-root.
Add a second article to confirm that sections do not overlap.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
Apply CSS to an iframe: Same-Origin Styling in HTML
Learn why parent-page CSS does not style iframe content, how same-origin rules work, and practical ways to style embedded pages safely.
Apply Multiple CSS Transforms: rotate() and translate()
Learn how to combine multiple CSS transform functions such as rotate() and translate(), understand transform order, and avoid overwritten rules.