overflow & block formatting context
The overflow property controls what happens when content exceeds an element's dimensions. Beyond the visible/hidden/scroll values, overflow has a powerful side effect: it creates a new block formatting context (BFC), which contains floated children, prevents margin collapse, and changes how the element interacts with floats. Understanding overflow is crucial for fixing layout bugs and working with floats.
Overflow values and behaviour
Value | Overflow content | Creates BFC? | Use case |
|---|---|---|---|
| Spills out | No | Default, content flows normally |
| Clipped | Yes | Hide overflow, contains floats |
| Scrollable | Yes | Always show scrollbars |
| Scrollable if needed | Yes | Show scrollbars when needed |
| Clipped (strict) | No | Newer, stricter clipping |
/* Overflow: visible (default) */
.container {
width: 200px;
height: 100px;
overflow: visible;
/* Content that exceeds dimensions spills out */
}
<!-- Result -->
[Container with]
[spillover text]
that extends outside
/* Overflow: hidden */
.container {
width: 200px;
height: 100px;
overflow: hidden;
/* Content beyond dimensions is clipped */
}
<!-- Result -->
[Container with]
[spillover text (clipped)]
/* Overflow: scroll */
.container {
width: 200px;
height: 100px;
overflow: scroll;
/* Scrollbars always visible */
}
<!-- Result -->
[Container with ⬚]
[spillover text ⬚]
[================⬚] scrollbar always shown
/* Overflow: auto */
.container {
width: 200px;
height: 100px;
overflow: auto;
/* Scrollbars only if content overflows */
}
<!-- Result (with overflow) -->
[Container with ⬚]
[spillover text ⬚]
[================⬚]
<!-- Result (without overflow) -->
[Container with]
[content fits ]
/* No scrollbars shown */Creating a block formatting context (BFC)
A block formatting context is a new layout scope. Elements inside a BFC don't affect elements outside it. Using overflow creates a BFC, which solves many layout problems.
<!-- Problem: margin collapse without BFC -->
<div class="parent">
<div class="child">Child</div>
</div>
.parent {
background: blue;
/* position: static (default) */
}
.child {
margin-top: 20px; /* collapses with parent! */
}
<!-- Result -->
[Blue parent]
[Child starts 20px from top? No, margin collapses]
Child starts at top
<!-- Solution: create BFC with overflow -->
.parent {
background: blue;
overflow: auto; /* creates BFC */
}
.child {
margin-top: 20px; /* no collapse */
}
<!-- Result -->
[Blue parent]
[Child starts 20px from top]
<!-- Other ways to create BFC -->
.parent {
display: flex; /* BFC */
display: grid; /* BFC */
position: absolute; /* BFC */
position: fixed; /* BFC */
position: relative; /* not BFC */
float: left; /* BFC */
overflow: hidden/auto; /* BFC */
}Overflow containing floats
Using overflow: auto or overflow: hidden on a parent that contains floated children prevents float collapse.
<!-- Float collapse without BFC -->
<div class="container">
<div class="float-left">Column 1</div>
<div class="float-left">Column 2</div>
</div>
.container {
background: blue;
/* All children are floated, container height is 0 */
}
.float-left {
float: left;
width: 50%;
height: 200px;
/* doesn't affect parent height */
}
<!-- Result: blue container appears as thin line -->
<!-- Solution: overflow creates BFC -->
.container {
background: blue;
overflow: auto; /* contains floats */
/* Height now calculated correctly */
}
.float-left {
float: left;
width: 50%;
height: 200px; /* affects parent height */
}
<!-- Result: blue container is 200px tall -->Text wrapping around floats with overflow
A key property of BFC: elements inside a BFC don't wrap around floats outside the BFC.
<!-- Text wrapping around float (no BFC) -->
<img class="float-left" src="image.jpg">
<p>Text flows around the image...</p>
.float-left {
float: left;
width: 150px;
}
.text-box {
/* Not in BFC, so text wraps */
This box fits next to the float
and wraps around its edges.
}
<!-- Solution: create BFC on text box -->
.text-box {
overflow: auto; /* creates BFC */
/* Box no longer wraps around float */
}
Result:
[Image] [Text box stretches full width,]
[doesn't wrap around image ]
<!-- Other ways to prevent wrapping -->
.text-box {
display: flex; /* BFC */
display: grid; /* BFC */
float: left; /* BFC, with width */
}Overflow-x and overflow-y
You can control horizontal and vertical overflow independently.
/* Separate control for x and y */
.container {
overflow-x: auto; /* horizontal scrolling */
overflow-y: hidden; /* vertical clipping */
}
/* Horizontal scrolling (common for tables) */
.table-container {
overflow-x: auto;
overflow-y: visible;
}
<table><!-- wide table --></table>
<!-- Table scrolls horizontally on small screens -->
/* Vertical scrolling only (common for lists) */
.dropdown-menu {
max-height: 300px;
overflow-y: auto; /* scroll if taller than 300px */
overflow-x: hidden; /* hide horizontal overflow */
}
/* No horizontal scrolling, vertical only */Practical overflow patterns
/* Fix float collapse and contain floats */
.float-container {
overflow: auto;
}
.float {
float: left;
width: 50%;
}
/* Prevent text wrapping around float */
.content {
overflow: hidden; /* or overflow: auto */
}
/* Scrollable container for tall content */
.scrollable-list {
max-height: 400px;
overflow-y: auto;
overflow-x: hidden;
}
/* Table with horizontal scroll on mobile */
.table-wrapper {
overflow-x: auto;
overflow-y: visible;
}
table {
width: 100%;
min-width: 800px; /* forces scrolling on small screens */
}
/* Stop margin collapse */
.container {
overflow: auto; /* unnecessary usually, but works */
}
/* Better: just use padding */
.container {
padding-top: 0.01px; /* tiny padding prevents collapse */
}When overflow creates unexpected effects
Creating a BFC with overflow can have side effects. Be aware of what changes when you use overflow.
<!-- Overflow has side effects -->
/* Margins won't collapse anymore */
.parent {
overflow: auto;
}
.child {
margin-top: 20px; /* no longer collapses with parent */
}
/* Positioned children with overflow parent */
.parent {
position: relative;
overflow: auto;
}
.child {
position: absolute;
/* Still positions relative to parent */
/* But now clipped if it exceeds parent bounds */
}
/* Box-shadow and outline may be clipped */
.element {
overflow: hidden;
}
.element:focus {
outline: 2px solid blue; /* outline may be clipped */
box-shadow: 0 0 10px blue; /* shadow may be clipped */
}
/* Solution: use overflow: clip or visible on focus */
.element:focus {
overflow: visible; /* temporarily show overflow */
}