CSS overflow property
CSS overflow defines what happens when content is too big for its container: it can spill out, get clipped, or become scrollable.
Theory
TL;DR
- Fish tank analogy:
visiblelets water spill everywhere,hiddenseals it shut,scrolladds permanent drain pipes,autoadds pipes only when the tank overflows. - Main difference:
autoshows scrollbars only when content exceeds the box;scrollalways renders them. overflow: hiddenalso triggers a Block Formatting Context (BFC), which wraps floated children automatically.- Decision rule:
hiddento crop UI cleanly (cards, avatars),autofor dynamic content like chat logs or sidebars.
Quick example
/* Clips child to rounded corners - standard card pattern */
.card {
overflow: hidden;
border-radius: 12px;
width: 300px;
height: 200px;
}
/* Scrollbar appears only when messages exceed the container */
.chat {
overflow-y: auto;
max-height: 400px; /* Without this, the box just grows forever */
}The first rule crops any child that sticks outside the card boundary. The second keeps a fixed-height message list and adds a vertical scrollbar only when needed.
Values at a glance
| Value | Behavior |
|---|---|
visible | Default. Content renders outside the box. |
hidden | Clips content. No scrollbar. JS scrollTop still works. |
scroll | Scrollbars always visible, even on short content. |
auto | Scrollbar appears only when content overflows. |
clip | Like hidden, but JS scrollTop has no effect. |
Key difference
auto and scroll both make content scrollable, but scroll always renders scrollbar tracks regardless of content size. On some platforms that reserves space and shifts layout. auto is the safer default. Use scroll when you need the scrollbar always present visually, for example a horizontal navigation row where you want a hint that content continues off-screen.
overflow-x and overflow-y
You can control axes independently:
/* Horizontal scrolling row, vertical overflow hidden */
.tag-list {
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
-webkit-overflow-scrolling: touch; /* Native feel on iOS */
}This pattern appears in tag lists, horizontal carousels, and Bootstrap's .table-responsive component.
When to use
- Fixed card with long text:
overflow: hidden(clean crop) - Chat log, sidebar, modal body:
overflow-y: autowith amax-height - Horizontal nav or data table:
overflow-x: autofor small screens - Body element during modal open:
overflow: hiddenblocks background scroll - Rounded card or avatar:
overflow: hiddenclips the image to the border shape
overflow: hidden and BFC
Setting overflow to hidden, auto, or scroll creates a Block Formatting Context. The practical result: the container wraps its floated children instead of collapsing to zero height. This was the standard float-clearing technique before display: flow-root existed. You will still see it in older codebases.
.container {
overflow: hidden; /* BFC: wraps floated children, no height collapse */
}Common mistakes
Forgetting height with overflow: auto.
/* Wrong: box grows forever, scroll never triggers */
.list { overflow-y: auto; }
/* Fix: constrain the height */
.list { overflow-y: auto; height: 300px; }Without a height or max-height, the container just expands. There is nothing to overflow against.
Assuming overflow: hidden clips both axes.
/* Child can still spill horizontally */
.parent { overflow: hidden; }
.child { width: 500px; }
/* Fix: target the axis you need */
.parent { overflow-x: hidden; }Using overflow: scroll on mobile. Always-visible scrollbars can conflict with native scroll behavior, producing double scroll tracks on some platforms. Use overflow: auto with -webkit-overflow-scrolling: touch for a native feel.
Mixing up hidden and clip. Both clip visually. clip also blocks JS scrollTop. If you need to control scroll position in code, use hidden.
Real-world usage
- shadcn/ui Dialog:
overflow: autoon.modal-bodyfor scrollable modal content - TailwindCSS:
overflow-hiddenon card components in Next.js templates - Bootstrap:
.table-responsiveusesoverflow-x: autofor wide tables on mobile - VS Code: sidebar panels combine
overflow: hiddenwith resize handles
Follow-up questions
Q: What is the difference between overflow: hidden and overflow: clip?
A: Both clip content visually. clip also blocks all scroll events, including JS scrollTop. hidden allows programmatic scrolling. Use hidden if you ever need to move scroll position in code.
Q: How does overflow interact with flexbox?
A: Setting overflow on a flex container only clips or scrolls the overflow. It does not affect how flex items are aligned. Set overflow on the item itself if you want individual items to scroll.
Q: Why does overflow-x: auto show no scrollbar when content fits?
A: Browsers hide the scrollbar track until content actually overflows. That is the whole point of auto. Use scroll if you need the track always visible.
Q: How does overflow: hidden on body prevent background scroll during a modal, and what breaks on iOS Safari?
A: It clips the body's scrollable area so the user cannot scroll behind the modal. iOS Safari's momentum scroll can bypass this. The fix: body { overflow: hidden; position: fixed; width: 100%; }. Be aware this resets scrollY to 0, so save and restore the position manually if needed.
Examples
Clipping an image to a card shape
<style>
.card {
width: 250px;
height: 180px;
overflow: hidden;
border-radius: 12px;
}
.card img {
width: 100%;
height: 100%;
object-fit: cover;
}
</style>
<div class="card">
<img src="photo.jpg" alt="Profile photo" />
</div>Without overflow: hidden, the image corners stick out past the rounded border. With it, the image clips to the card shape. This is the same pattern TailwindCSS uses on card components in its default templates.
Scrollable chat container
function ChatMessages({ messages }) {
return (
<div style={{
height: '400px',
overflowY: 'auto', /* Scroll only when needed */
border: '1px solid #ccc',
padding: '8px'
}}>
{messages.map(msg => (
<div key={msg.id}>{msg.text}</div>
))}
</div>
);
}The container stays at 400px. Once messages push past that height, a scrollbar appears. Remove height: 400px and the scrollbar never shows up, no matter how many messages load. That is the mistake that shows up most often in code review.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.