What CSS float is (and why it exists)
The CSS float property is one of those “historically important” features that still shows up in real
websites today.
Floats were originally meant for one main job: letting text wrap around an element (like an image in a newspaper
layout).
Later, we all collectively decided to use floats for entire page layouts (columns, sidebars, grids) because we didn’t
have
flex or grid yet. It worked… but it also created a bunch of weird problems you had to fix
with clearing.
Today, floats are still useful, but usually for what they were born to do:
wrapping inline content around a floated element.
For layout, prefer flex and grid most of the time.
Float is not positioning
A float is not the same as position: absolute, and it’s not a modern layout system like flexbox.
A float “nudges” a box to the left or right edge of its container, and then the rest of the content flows around it.
That “flows around it” part is the whole story. If you remember only one thing from this tutorial: remember that.
.float-me {
float: left;
}
.float-me {
float: right;
}
.float-me {
float: none;
}
*,
::before,
::after {
box-sizing: border-box;
}
.wrap {
font-family: ui-monospace, SFMono-Regular, Menlo;
line-height: 1.5;
}
.float-me {
width: 160px;
height: 110px;
border: 3px solid #111;
background: #f2f2f2;
padding: 10px;
margin: 0 14px 10px 0;
}
.note {
border: 2px dashed #111;
padding: 10px;
background: #fff;
}
I float.This paragraph is normal flow text. When the box floats left or right, the text flows around it. When float is none, the box stays in normal flow and the text appears below it.
float: left and float: right (the core behavior)
Floats have two main values you’ll use:
-
float: leftpushes the element to the left side of its container. -
float: rightpushes the element to the right side of its container.
The element is still a box with width and height, but it is taken out of the normal flow in a special way: text and inline content will wrap around it.
A classic floated image example
This is the most “correct” use of floats: an image-like element, floated left, with text wrapping on the right.
.media {
float: left;
margin-right: 14px;
}
.media {
float: right;
margin-left: 14px;
margin-right: 0;
}
.media {
float: none;
margin-right: 0;
margin-left: 0;
}
*,
::before,
::after {
box-sizing: border-box;
}
.article {
padding: 16px;
font-family: system-ui, -apple-system, Segoe UI;
line-height: 1.6;
max-width: 760px;
}
.media {
width: 180px;
aspect-ratio: 4 / 3;
border: 3px solid #111;
background-image: url(https://picsum.photos/360/270);
background-size: cover;
background-position: center;
margin-bottom: 10px;
}
.article p {
margin: 0 0 10px 0;
}
Floats are perfect for this: an image-like box plus a bunch of text that wraps around it. This is the “newspaper” layout that floats were designed for.
If the text is long enough, it keeps flowing next to the floated element until it clears the bottom, then it continues full width below.
Try switching between left, right, and none.
What clear does (and why you need it)
The clear property is the “don’t wrap around floats” switch.
It tells an element:
-
clear: leftmeans “don’t sit next to floats on the left”. -
clear: rightmeans “don’t sit next to floats on the right”. -
clear: bothmeans “don’t sit next to floats on either side”.
When an element is cleared, it is pushed down until it’s below the floated element(s).
.float-box {
float: left;
}
.after {
clear: none;
}
.float-box {
float: left;
}
.after {
clear: left;
}
.float-box {
float: left;
}
.after {
clear: both;
}
*,
::before,
::after {
box-sizing: border-box;
}
.stage {
padding: 16px;
font-family: ui-monospace, SFMono-Regular, Menlo;
}
.float-box {
width: 220px;
height: 90px;
border: 3px solid #111;
background: #f2f2f2;
padding: 10px;
margin: 0 12px 12px 0;
}
.after {
border: 2px dashed #111;
padding: 10px;
background: #fff;
}
I float left.I’m the next element in the HTML. If I don’t clear, I can sit beside the float (and wrap around it). If I clear, I’m forced below.
The clearfix pattern (classic float fix)
If you’ve ever seen a class named .clearfix, it exists because floats can escape their parent.
The clearfix hack creates an invisible block after the floated children that clears them.
.thumb {
float: left;
}
.clearfix::after {
content: "";
display: block;
clear: both;
}
*,
::before,
::after {
box-sizing: border-box;
}
.demo {
padding: 16px;
font-family: system-ui, -apple-system, Segoe UI;
}
.box {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
max-width: 720px;
}
.thumb {
width: 170px;
height: 120px;
border: 3px solid #111;
background-image: url(https://picsum.photos/340/240);
background-size: cover;
background-position: center;
margin: 0 14px 10px 0;
}
p {
margin: 0 0 10px 0;
line-height: 1.6;
}
This container uses a clearfix. The floated thumb is now “contained”, so the border/background wraps it.
Clearfix is still seen in legacy code, but
display: flow-rootis often cleaner today.
Building columns with floats (the old-school layout)
Before flexbox and grid, floats were a common way to create columns. You float the columns left, give them widths, and then clear the container.
This still works, and it’s useful to understand when you’re reading older CSS.
Two-column layout with floats
In this example, the sidebar floats left and the main content sits next to it.
We’ll use display: flow-root on the container to avoid the collapsing parent problem.
.layout {
display: flow-root;
}
.sidebar {
float: left;
width: 32%;
}
.main {
float: left;
width: 68%;
}
.layout {
display: flow-root;
}
.sidebar {
float: right;
width: 32%;
}
.main {
float: left;
width: 68%;
}
.layout {
display: flow-root;
}
.sidebar {
float: left;
width: 240px;
}
.main {
float: left;
width: calc(100% - 240px);
}
*,
::before,
::after {
box-sizing: border-box;
}
.layout {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
font-family: ui-monospace, SFMono-Regular, Menlo;
}
.col {
border: 3px solid #111;
background: #fff;
padding: 10px;
min-height: 120px;
}
.sidebar {
background: #fff;
}
.main {
background: #fff;
}
.col p {
margin: 0 0 8px 0;
line-height: 1.5;
}
Main
This is the content area.
Floats can make columns, but flex/grid is easier today.
Why float columns are fragile
- Columns don’t “equalize” height naturally.
- Spacing between columns often requires margin math (and can cause wrapping if you overshoot 100%).
- Reordering content is awkward compared to flex/grid.
The “media object” pattern (floats shine here)
A super practical float pattern is: small media on one side, content on the other. This is still common for avatars, thumbnails, or icons beside text.
A common “gotcha” is that the text block might wrap under the float if the layout gets too narrow.
One simple fix is to create a new block formatting context on the text area with overflow: auto.
.avatar {
float: left;
margin-right: 12px;
}
.avatar {
float: left;
margin-right: 12px;
}
.body {
overflow: auto;
}
.avatar {
float: left;
margin-right: 12px;
}
.card {
display: flow-root;
}
*,
::before,
::after {
box-sizing: border-box;
}
.card {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
max-width: 720px;
font-family: system-ui, -apple-system, Segoe UI;
line-height: 1.6;
}
.avatar {
width: 72px;
height: 72px;
border: 3px solid #111;
border-radius: 999px;
background-image: url(https://picsum.photos/200/200);
background-size: cover;
background-position: center;
margin-bottom: 10px;
}
.body h4 {
margin: 0 0 6px 0;
font-size: 18px;
}
.body p {
margin: 0;
}
Floated avatar
This is a classic “media object”. The avatar floats, and the text wraps naturally. Try the different snippets to see how you can keep things tidy.
Float and width: how wrapping happens
Floats often “look fine” until the combined widths (plus margins and borders) don’t fit on one line. Then the second floated element drops down to the next “line” of available space.
This is why float-based grids required careful math and often used percentages.
.item {
float: left;
width: 33.333%;
}
.item {
float: left;
width: 33.333%;
margin-right: 2%;
}
.item {
float: left;
width: 32%;
margin-right: 2%;
}
.item:last-child {
margin-right: 0;
}
*,
::before,
::after {
box-sizing: border-box;
}
.grid {
display: flow-root;
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
font-family: ui-monospace, SFMono-Regular, Menlo;
}
.item {
border: 3px solid #111;
background: #fff;
padding: 14px 10px;
text-align: center;
margin-bottom: 10px;
}
OneTwoThree
The “100% problem” in float grids
If you set three columns to width: 33.333% and then add margins, borders, and padding,
you can accidentally exceed 100% and cause wrapping.
box-sizing: border-box helps a lot, but float grids still require careful spacing decisions.
This is one reason flexbox and grid became so popular: fewer surprise math moments.
Common float gotchas (and how to fix them)
Gotcha: text or elements overlap floats
If you have elements after a float and you don’t want them to wrap beside it, you likely need
clear.
-
Use
clear: bothwhen you want a clean break below floats. -
Or “contain” floats with
display: flow-rooton the parent so later content starts after the container.
Gotcha: parent background doesn’t wrap the float
This is the collapsing parent problem again.
Preferred fix today: display: flow-root on the container.
Gotcha: floats for layout are hard to maintain
If you’re building columns, cards, or full page layout, ask yourself: “Am I only using floats because I saw it in a 2011 tutorial?”
For layout, use:
-
display: flexfor one-dimensional layouts (rows or columns). -
display: gridfor two-dimensional layouts (rows and columns together).
Float vs Flex vs Grid: when to use what
Here’s a beginner-friendly rule of thumb:
-
Use
floatwhen you want content to wrap around something (like an image, avatar, thumbnail). -
Use
flexwhen you want items aligned in a row or column with easy spacing and alignment. -
Use
gridwhen you want a true grid layout (rows and columns) with fewer hacks.
.figure {
float: left;
margin-right: 14px;
}
.row {
display: flex;
gap: 10px;
}
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
*,
::before,
::after {
box-sizing: border-box;
}
.demo {
padding: 16px;
font-family: system-ui, -apple-system, Segoe UI;
line-height: 1.6;
}
.figure {
width: 160px;
aspect-ratio: 4 / 3;
border: 3px solid #111;
background-image: url(https://picsum.photos/320/240);
background-size: cover;
background-position: center;
margin-bottom: 10px;
}
.note {
border: 2px dashed #111;
padding: 10px;
background: #fff;
margin-bottom: 14px;
}
.row > div,
.grid > div {
border: 3px solid #111;
background: #f2f2f2;
padding: 12px;
text-align: center;
font-family: ui-monospace, SFMono-Regular, Menlo;
}
Snippet 1: float wraps text around an element (great for “image + text”). Snippet 2: flex aligns boxes in a row. Snippet 3: grid makes a real grid.
This paragraph wraps around the floated figure. That’s the float superpower. When you switch to flex or grid, you’ll see we’re not wrapping text anymore, we’re arranging layout boxes.
ABC123
Learn more about display: flex; in the CSS Flexbox Interactive Tutorial, and
display: grid; in the CSS Grid
Interactive Tutorial.
Practical float checklist
When you’re using floats, run through this quick checklist:
- Do I actually want text to wrap? If not, floats might be the wrong tool.
-
Is the parent containing the float? Use
display: flow-rooton the container, or clearfix. -
Do elements after the float need to start below it? Use
clear: bothon the next block, or clear the container. - Did I account for width + padding + border + margin? Float layouts wrap if the math goes over.
Final notes: floats are “legacy” but still worth knowing
Floats aren’t dead, they’re just specialized. You’ll still see them in older codebases, and they’re genuinely handy for wrapping content around media.
If you’re building modern layouts, reach for flexbox and grid first. If you’re reading older CSS, understanding floats will make everything feel a lot less mysterious. And that’s a win.
