Clear Float: Solving Height Collapse Problems in Float Layout â
In the previous article, we learned about float's principles and applications. Although float is powerful, it also brings a headache problem: height collapse. Just like taking balloons out of a box, the box will instantly deflate, when all elements in a container float, the container will lose height. This article will teach you how to elegantly solve this problem.
Height Collapse Problem Brought by Float â
What is Height Collapse â
Height collapse is the most common and confusing problem for beginners with float. Let's first look at a specific example:
<div class="container">
<div class="float-box">Floated element 1</div>
<div class="float-box">Floated element 2</div>
<div class="float-box">Floated element 3</div>
</div>
<div class="next-section">I'm the next section</div>.container {
border: 3px solid #f44336;
background-color: #fff3e0;
padding: 10px;
}
.float-box {
float: left;
width: 150px;
height: 100px;
margin: 10px;
background-color: #2196f3;
color: white;
padding: 15px;
}
.next-section {
background-color: #4caf50;
color: white;
padding: 20px;
}In the browser, you'll see:
.container's height collapses to almost 0 (only padding height)- Border and background cannot display correctly
.next-sectionmoves up, may overlap with floated elements- Entire layout looks messy
Why Does Height Collapse â
This starts from how browsers calculate element height. When browser calculates an element's height, it checks the child elements it contains. But floated elements have left normal document flow, browser "ignores" these floated child elements when calculating parent element height, as if they don't exist.
Using a metaphor: imagine a transparent balloon floating above a box. Although the balloon looks like it's in the box, the box when weighing won't count the balloon, because the balloon isn't really "pressing" on the box bottom.
Clear Property: Float's Nemesis â
Before learning various methods to clear float, we need to first understand the clear property, because it's the foundation of clearing float.
Four Clear Values â
.element {
clear: none; /* Default value, allows floated elements on both sides */
clear: left; /* Left side doesn't allow floated elements */
clear: right; /* Right side doesn't allow floated elements */
clear: both; /* Both sides don't allow floated elements */
}How Clear Works â
When an element has the clear property set, browser ensures the specified side (left, right or both) of this element has no floated elements. If there are floated elements, this element will be "pushed" below the floated elements.
<div class="container">
<div class="float-left">Left float</div>
<div class="float-left">Left float</div>
<div class="clear-element">I cleared left float</div>
</div>.float-left {
float: left;
width: 150px;
height: 100px;
margin: 10px;
background-color: #2196f3;
}
.clear-element {
clear: left; /* Left side doesn't allow floated elements */
background-color: #4caf50;
padding: 20px;
}.clear-element will be pushed below the two floated elements, ensuring no floated elements on its left side.
Using Clear to Solve Height Collapse (Traditional Method) â
The most direct method is to add an empty element to clear float after floated elements:
<div class="container">
<div class="float-box">Float 1</div>
<div class="float-box">Float 2</div>
<div class="clear"></div>
<!-- Empty element to clear float -->
</div>.float-box {
float: left;
width: 200px;
height: 150px;
}
.clear {
clear: both;
}This method can work, but has obvious drawbacks:
- Needs to add extra HTML elements
- Breaks separation of structure and style principle
- Not elegant enough, difficult to maintain
Methods to Clear Float â
There are multiple methods to clear float, each method has its own advantages and disadvantages. Let's learn them one by one.
Method 1: Using Overflow Property â
Setting overflow property (hidden or auto) on parent container can create BFC (Block Formatting Context), thus containing floated elements.
.container {
overflow: hidden; /* Or auto */
border: 3px solid #f44336;
background-color: #fff3e0;
padding: 10px;
}
.float-box {
float: left;
width: 150px;
height: 100px;
margin: 10px;
}How it works: overflow: hidden creates a new BFC, BFC will calculate floated element height. We'll explain BFC in detail later.
Advantages:
- Concise code, just one line of CSS
- Doesn't need extra HTML elements
Disadvantages:
overflow: hiddenwill clip overflowing contentoverflow: automay show scrollbars- May affect internal absolutely positioned elements
Applicable scenarios: Certain content won't overflow, and don't need to use absolute positioning.
Actual example:
<div class="card-container">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
</div>.card-container {
overflow: hidden; /* Clear float */
padding: 20px;
background-color: #f5f5f5;
}
.card {
float: left;
width: 200px;
margin: 10px;
padding: 20px;
background-color: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}Method 2: Using Pseudo-element Clearfix (Most Recommended) â
This is currently the most commonly used and most recommended method. Clear float by adding a pseudo-element after parent element.
Basic version:
.clearfix::after {
content: "";
display: block;
clear: both;
}How it works:
content: ""creates an empty pseudo-elementdisplay: blockmakes pseudo-element a block elementclear: bothclears float on both sides
How to use:
<div class="container clearfix">
<div class="float-box">Float 1</div>
<div class="float-box">Float 2</div>
<!-- ::after pseudo-element will automatically add here -->
</div>.clearfix::after {
content: "";
display: block;
clear: both;
}
.float-box {
float: left;
width: 200px;
}Complete version (compatible with old browsers):
.clearfix::before,
.clearfix::after {
content: "";
display: table;
}
.clearfix::after {
clear: both;
}
/* Compatible with IE6/7 */
.clearfix {
*zoom: 1;
}This version also handles margin collapse problem. display: table creates an anonymous table cell, can prevent margin collapse.
Modern version (recommended):
.clearfix {
display: flow-root;
}display: flow-root is a modern property specifically for creating BFC, its purpose is to contain float and prevent margin collapse.
Solution compatible with both:
/* Modern browsers */
.clearfix {
display: flow-root;
}
/* Browsers that don't support flow-root fallback to pseudo-element solution */
@supports not (display: flow-root) {
.clearfix::after {
content: "";
display: block;
clear: both;
}
}Advantages:
- Doesn't need extra HTML elements
- Doesn't affect layout and style
- Strong reusability
- This is industry best practice
Disadvantages:
- Need to remember to add clearfix class to parent container
- Need to understand pseudo-element concept
Applicable scenarios: Vast majority of situations needing to clear float, this is the most recommended method.
Method 3: Float Parent Container â
Let parent container also float, can contain floated child elements.
.container {
float: left;
width: 100%;
}
.float-box {
float: left;
}How it works: Floated elements will contain floated child elements.
Advantages:
- Simple and direct
Disadvantages:
- After parent container floats, problem transfers to higher level
- Affects overall layout
- Rarely actually used
Applicable scenarios: Almost never used, not recommended.
Method 4: Set Parent Container Height â
Directly set fixed height for parent container.
.container {
height: 300px; /* Fixed height */
}Advantages:
- Direct and effective
Disadvantages:
- Not flexible, cannot adapt to content changes
- Difficult to maintain in responsive design
- Content overflow if too much content
- Blank space if too little content
Applicable scenarios: Special situations where content height is certain and won't change, generally not recommended.
Method 5: Using Display: Table â
Setting parent container to display: table can contain floated elements.
.container {
display: table;
width: 100%;
}How it works: Table elements create BFC, thus containing floated elements.
Advantages:
- Can contain float
- Doesn't affect content overflow
Disadvantages:
- Changes element's display type
- May affect other layout
- Rarely used now
Applicable scenarios: Some special situations, but generally not as convenient as overflow or clearfix.
Understanding BFC (Block Formatting Context) â
We mentioned BFC several times before, now let's understand this important concept in detail.
What is BFC â
BFC (Block Formatting Context) is a concept in CSS rendering mechanism. You can understand it as an independent "small world" or "independent rendering area" on the page.
In this "small world", internal element layout won't affect outside, outside also won't affect inside. Like a sealed box, no matter how much chaos inside, won't affect outside.
Ways to Create BFC â
The following ways will all create new BFC:
/* 1. Root element html (naturally a BFC) */
/* 2. float not none */
.element {
float: left; /* Or right */
}
/* 3. position is absolute or fixed */
.element {
position: absolute; /* Or fixed */
}
/* 4. display is inline-block, table-cell, table-caption */
.element {
display: inline-block;
}
/* 5. Direct children of flex/inline-flex containers (if they themselves are not flex containers) */
/* 6. Direct children of grid/inline-grid containers (if they themselves are not grid containers) */
/* 7. overflow not visible and clip */
.element {
overflow: hidden; /* Or auto, scroll */
}
/* 8. display: flow-root (specifically for creating BFC) */
.element {
display: flow-root;
}
/* 9. contain value is layout, content or paint */
.element {
contain: layout;
}
/* 10. column-count or column-width not auto */
.element {
column-count: 2;
}Among these, display: flow-root is specifically designed for creating BFC, with no other side effects.
Three Main BFC Features â
Feature 1: Contains Internal Float â
This is the principle of using BFC to clear float. BFC will calculate floated element height.
<div class="bfc-container">
<div class="float-child">Floated element</div>
</div>.bfc-container {
display: flow-root; /* Create BFC */
background-color: #f5f5f5;
border: 2px solid #2196f3;
}
.float-child {
float: left;
width: 200px;
height: 150px;
background-color: #4caf50;
}Container height will include floated child element.
Feature 2: Excludes External Float â
BFC area won't overlap with external floated elements. This can be used to implement adaptive two-column layout.
<div class="sidebar">Sidebar (floated)</div>
<div class="main-content">Main content (BFC)</div>.sidebar {
float: left;
width: 250px;
height: 400px;
background-color: #e3f2fd;
}
.main-content {
display: flow-root; /* Create BFC, won't be covered by floated element */
background-color: #fff3e0;
padding: 20px;
min-height: 400px;
}.main-content will automatically avoid floated .sidebar, forming adaptive two-column layout.
Feature 3: Prevents Margin Collapse â
Normally, vertical margins of adjacent block elements will collapse (take larger value). But if they belong to different BFCs, margins won't collapse.
<div class="container">
<div class="box">Box 1 (margin-bottom: 50px)</div>
<div class="box">Box 2 (margin-top: 30px)</div>
</div>.box {
background-color: #e3f2fd;
padding: 20px;
margin: 50px 0;
}Normally, spacing between two boxes is 50px (two margins collapse, take larger value).
If we make second box create BFC:
.box:nth-child(2) {
display: flow-root; /* Create BFC */
}Now spacing between two boxes is 80px (50px + 30px, margins no longer collapse).
BFC Application Scenarios â
Scenario 1: Clear float
.container {
display: flow-root; /* Create BFC to contain float */
}Scenario 2: Adaptive two-column layout
.sidebar {
float: left;
width: 300px;
}
.main {
display: flow-root; /* Create BFC to avoid float */
}Scenario 3: Prevent margin collapse
.parent {
display: flow-root; /* Create BFC */
}
.child {
margin-top: 50px; /* Won't penetrate parent element */
}Normally, child element's margin-top may "penetrate" parent element, making parent element move down as a whole. Creating BFC can prevent this.
Best Practices in Actual Development â
Recommended Clearfix Implementation â
Combining modern browsers and compatibility considerations, this is the recommended implementation:
/* Modern browsers first */
.clearfix {
display: flow-root;
}
/* Browsers that don't support flow-root fallback */
@supports not (display: flow-root) {
.clearfix::after {
content: "";
display: block;
clear: both;
}
}Or, if you don't need to consider very old browsers, use directly:
.clearfix {
display: flow-root;
}Encapsulate Reusable Clear Float Classes â
/* Basic clearfix */
.cf::after {
content: "";
display: table;
clear: both;
}
/* Version that prevents margin collapse */
.cf-full::before,
.cf-full::after {
content: "";
display: table;
}
.cf-full::after {
clear: both;
}
/* Modern version */
.cf-modern {
display: flow-root;
}Usage Examples â
<!-- Card container -->
<div class="product-grid cf">
<div class="product-card">Product 1</div>
<div class="product-card">Product 2</div>
<div class="product-card">Product 3</div>
</div>
<!-- Navigation bar -->
<nav class="navbar cf">
<a href="#" class="nav-item">Home</a>
<a href="#" class="nav-item">Products</a>
<a href="#" class="nav-item">About</a>
</nav>
<!-- Image gallery -->
<div class="gallery cf">
<img src="1.jpg" class="gallery-img" />
<img src="2.jpg" class="gallery-img" />
<img src="3.jpg" class="gallery-img" />
</div>/* All float containers share clearfix */
.cf {
display: flow-root;
}
.product-card {
float: left;
width: calc(33.333% - 20px);
margin: 10px;
}
.nav-item {
float: left;
padding: 15px 20px;
}
.gallery-img {
float: left;
width: calc(25% - 20px);
margin: 10px;
}Clear Float Method Comparison â
| Method | Advantages | Disadvantages | Recommendation |
|---|---|---|---|
| Empty div + clear | Simple direct | Breaks HTML structure | â |
| overflow: hidden | Concise code | Hides overflow | âââ |
| overflow: auto | Contains float | May show scrollbars | ââ |
| Pseudo-element clearfix | Doesn't break structure | Need understand pseudo-elements | âââââ |
| display: flow-root | Most elegant | Slightly worse compatibility | âââââ |
| Float parent | Can contain float | Problem transfers | â |
| Fixed height | Direct effective | Not flexible | â |
| display: table | Can contain float | Changes display type | ââ |
Common Problems and Solutions â
Problem 1: Clearfix Doesn't Work â
Check if forgot to set content:
/* â Wrong: missing content */
.clearfix::after {
display: block;
clear: both;
}
/* â
Correct */
.clearfix::after {
content: ""; /* Must have */
display: block;
clear: both;
}Problem 2: Overflow: Hidden Hides Content â
If content may overflow, don't use overflow: hidden, change to clearfix:
/* â Problem: child elements beyond will be hidden */
.container {
overflow: hidden;
}
/* â
Solution: use clearfix */
.container {
display: flow-root;
}Problem 3: Margin Collapse Problem â
Child element margin penetrates parent element:
/* Problem */
.parent {
background-color: #f5f5f5;
}
.child {
margin-top: 50px; /* Will make parent move down as whole */
}
/* Solution: create BFC */
.parent {
display: flow-root;
background-color: #f5f5f5;
}Migrating from Float to Modern Layout â
Although we learned methods to clear float, in new projects, should prioritize considering modern layout solutions.
Float Layout â Flexbox â
/* Old way: Float + clearfix */
.container-old {
/* Need clearfix */
}
.item-old {
float: left;
width: 33.333%;
}
/* New way: Flexbox */
.container-new {
display: flex;
gap: 20px;
}
.item-new {
flex: 1;
}Float Layout â Grid â
/* Old way: Float */
.grid-old {
/* Need clearfix */
}
.grid-item-old {
float: left;
width: calc(25% - 15px);
margin-right: 15px;
margin-bottom: 15px;
}
.grid-item-old:nth-child(4n) {
margin-right: 0; /* Remove right margin for last in each row */
}
/* New way: Grid */
.grid-new {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 15px;
}Summary â
Clearing float is an essential skill for handling float layout, but in modern development, we have better choices.
Core Methods to Clear Float:
- Most recommended:
display: flow-rootor pseudo-element clearfix - Alternative:
overflow: hidden/auto(simple scenarios) - Not recommended: Empty div, float parent container, fixed height
BFC Importance:
- Contains internal float
- Excludes external float
- Prevents margin collapse
- Understanding BFC is key to mastering CSS layout
Best Practices:
- New projects prioritize using Flexbox or Grid
- Only use float when need text wrapping
- If must use float, use
display: flow-rootor clearfix to clear - Understand BFC concept and applications
Key Points:
- â
Using
display: flow-rootis the most modern solution - â Pseudo-element clearfix is classic and reliable solution
- â Understanding BFC can solve many layout problems
- â Avoid using empty div to clear float
- â Avoid using fixed height
- â New projects avoid using float for layout
Although float is no longer the first choice for layout in modern times, understanding clear float and BFC concepts is very important for mastering CSS layout mechanism. This knowledge not only helps you maintain old projects, but also lets you understand CSS working principles more deeply.