Boxes in CSS have a size, and sometimes the stuff inside them is just too big to fit. A long paragraph in a short box. A wide table in a narrow column. A list with fifty items in a card meant for five. So what happens to the part that doesn’t fit?
That’s exactly the question the overflow property answers. By default, content that’s too big simply spills out past the edges of its box — which is usually not what you want. overflow lets you take control: clip the extra, add a scrollbar, or deliberately let it show. It’s a small property with a big impact on how your layouts behave, and it’s behind almost every scrollable panel, modal, and contained list you’ve ever used. Let’s get it under your belt.
What overflow actually means
Every element in CSS is a box. When you give that box a fixed height or width, you’re drawing a hard boundary. The content inside doesn’t magically shrink to fit — if it’s bigger than the box, it overflows, meaning it extends beyond the box’s edges.
Here’s a box that’s too small for its text:
.box {
width: 200px;
height: 80px;
border: 2px solid #00B8E6;
}
<div class="box">
This is a long paragraph that contains far more text than
can comfortably fit inside a small 200 by 80 pixel box.
</div>
With no overflow rule, that extra text just pours out the bottom of the box, often overlapping whatever comes next on the page. The overflow property is how you decide what should happen to that overflowing content instead.
.box {
width: 200px;
height: 80px;
overflow: hidden; /* clip whatever doesn't fit */
}
Overflow only kicks in when there's a constraint
The overflow property has nothing to do unless the content is actually bigger than the box. And the box only has a fixed size when you give it one — usually a height (or max-height), sometimes a width. If your box grows freely to fit its content, there’s no overflow and overflow does nothing. So overflow problems almost always start with a height you set.
The four core values
overflow takes four values you’ll use constantly. Each handles the spillover differently:
| Value | What it does |
|---|---|
visible |
Content spills out past the box edges. This is the default. |
hidden |
Extra content is clipped — cut off and invisible, no scrollbar. |
scroll |
The box gets scrollbars, always, even if nothing overflows. |
auto |
The box gets scrollbars only when the content actually overflows. |
Let’s look at each one, because the differences matter in practice.
visible: the default spill
visible is what you get when you do nothing. The content simply ignores the box’s boundary and renders beyond it:
.card {
height: 100px;
overflow: visible; /* same as not setting it at all */
}
This is rarely what you want for a sized box, because the overflowing content can overlap other elements and make your layout look broken. But it’s the default, which is exactly why you need to know about the other three.
hidden: clip the extra
overflow: hidden cuts off anything that doesn’t fit. The overflowing content is still there in the DOM — it’s just not displayed, and there’s no way for the user to scroll to it:
.thumbnail {
width: 150px;
height: 150px;
overflow: hidden;
}
This is genuinely useful. It’s how you crop an oversized image to a square thumbnail, clip a preview of a long description, or stop a rogue element from breaking out of its container. Just be careful: because the clipped content is invisible and unreachable, you don’t want to accidentally hide something important.
hidden can silently swallow content
Since overflow: hidden clips without any scrollbar, the user has no idea there’s more content. If you clip a paragraph, the rest of it is just gone from their view. Use it for things that are genuinely meant to be cropped (images, decorative overflow), not for real text the reader needs to read.
scroll: always show scrollbars
overflow: scroll puts scrollbars on the box no matter what — even if the content fits perfectly and there’s nothing to scroll:
.panel {
height: 300px;
overflow: scroll;
}
Because the scrollbars appear unconditionally, you often see an empty, greyed-out scrollbar track even when scrolling isn’t possible. On most setups that looks a little off. scroll is useful when you specifically want the scrollbar always visible (so the layout width never jumps as content changes), but for everyday use, the next value is usually the better pick.
auto: scrollbars only when needed
overflow: auto is the smart one, and the value you’ll reach for most. It behaves like visible when the content fits, and adds scrollbars only when the content actually overflows:
.chat-log {
height: 400px;
overflow: auto;
}
If the chat log has three messages, no scrollbar. Once it fills up past 400px, a scrollbar appears so the user can scroll through. This “only when necessary” behavior is exactly what you want for scrollable panels, sidebars, modals, and long lists. When in doubt between scroll and auto, choose auto.
Controlling each axis: overflow-x and overflow-y
So far we’ve treated overflow as one setting, but content can overflow horizontally or vertically, and you can control each axis separately. overflow-x handles the horizontal (left–right) axis, and overflow-y handles the vertical (up–down) axis:
.table-wrap {
overflow-x: auto; /* scroll sideways for a wide table */
overflow-y: hidden; /* never scroll vertically */
}
This pair is the classic fix for a wide table on a narrow screen: let it scroll left and right inside its container, while the page itself stays put. When you write overflow: auto as a single value, you’re really setting both axes to auto at once.
/* These two are equivalent */
.a { overflow: auto; }
.b { overflow-x: auto; overflow-y: auto; }
The shorthand can take two values
overflow accepts two values: the first is overflow-x, the second is overflow-y. So overflow: hidden auto means “clip horizontally, scroll vertically when needed” — a common pattern for vertical-only scroll panels. One value applies to both axes.
A real example: a scrollable list
Let’s build something you’d genuinely ship — a fixed-height notifications panel that scrolls when it gets too full:
.notifications {
width: 320px;
height: 360px;
overflow-y: auto; /* vertical scroll only when needed */
border: 1px solid #d0d7de;
border-radius: 8px;
padding: 8px;
}
<div class="notifications">
<div class="item">New comment from John Doe</div>
<div class="item">Jane Doe started following you</div>
<div class="item">Your post was approved</div>
<!-- ...dozens more items... -->
</div>
The panel stays a tidy 360px tall no matter how many notifications arrive. A few items? It just sits there, no scrollbar. Fifty items? A scrollbar appears and the user scrolls through them, while everything around the panel stays exactly where it was. That’s the everyday power of overflow-y: auto.
The hidden side effect: containing floats
There’s one classic, slightly surprising behavior worth knowing. Setting overflow to anything other than visible creates what’s called a block formatting context — and one effect of that is the box will now stretch to contain its floated children:
.container {
overflow: hidden; /* now this box wraps around floated kids */
}
In the old days of float-based layouts, a parent would collapse to zero height if all its children were floated. Adding overflow: hidden (or auto) to the parent made it wrap around them properly. You’ll see this trick in older code. These days Flexbox and Grid have made floats mostly obsolete for layout, so you’ll meet this less often — but when you spot a lone overflow: hidden on a container with no obvious overflow, this is usually why.
overflow needs a height to scroll vertically
A super common confusion: you set overflow-y: auto but no scrollbar ever appears, and the box just keeps growing. That’s because the box has no height limit, so it never overflows — it just gets taller. For vertical scrolling you almost always need a fixed height or a max-height on the box. With max-height, the box grows naturally up to that limit, then starts scrolling.
Tidying scroll behavior
A couple of extra properties pair nicely with overflow on scrollable boxes. scroll-behavior: smooth makes programmatic and anchor-link scrolling glide instead of jumping:
.panel {
height: 400px;
overflow-y: auto;
scroll-behavior: smooth;
}
And overscroll-behavior: contain stops a scroll from “leaking” to the page behind once you reach the end of the box — handy for modals and chat windows so the background doesn’t scroll along with them:
.modal-body {
overflow-y: auto;
overscroll-behavior: contain;
}
These are small touches, but they’re the difference between a scroll area that feels polished and one that feels janky.
Best practices
A few habits that keep overflow from biting you:
- Reach for
auto, notscroll. You almost never want a permanent, empty scrollbar. Let the box add one only when it’s actually needed. - Pair vertical overflow with a height.
overflow-y: autodoes nothing without aheightormax-heightto overflow against. - Don’t hide real content.
overflow: hiddenis great for cropping images and decorative spill, but never use it to clip text a reader is supposed to read. - Use
overflow-x: autofor wide tables. Wrap a wide table or code block in a container that scrolls sideways, so it never blows out your page width on mobile. - Remember the float-containing trick. If you see
overflow: hiddenon a container that doesn’t seem to overflow, it’s probably there to contain floats or to start a fresh formatting context — don’t remove it blindly.
Wrapping up
The overflow property is how you tell a box what to do when its content is too big to fit, and you’ve now got the whole picture:
- Content that’s bigger than its box overflows — and overflow only happens when the box has a fixed size.
visiblelets it spill (the default),hiddenclips it,scrollalways shows scrollbars, andautoshows them only when needed.autois the everyday winner for scrollable panels, lists, and sidebars.overflow-xandoverflow-ycontrol the horizontal and vertical axes separately; the shorthand takes one or two values.- Vertical scrolling needs a
heightormax-heightto push against. - Setting overflow to a non-
visiblevalue also makes a box contain its floats — an old but still-seen side effect.
Overflow is one of those properties that quietly underpins a huge amount of real-world UI. Master it and you’ll stop fighting content that won’t behave, and start building panels, lists, and layouts that stay exactly as tidy as you designed them. Next up, we’ll look at how to keep boxes themselves predictable with box-sizing.