Suggest an editImprove this articleRefine the answer for “CSS overflow property”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**CSS overflow** controls what happens when content is too large for its container. `hidden` clips it with no scrollbar, `scroll` always shows scrollbars, `auto` adds them only when needed, `visible` (default) lets content spill out. ```css .card { overflow: hidden; border-radius: 12px; } .chat { overflow-y: auto; max-height: 400px; } ``` **Key:** prefer `auto` over `scroll` in most cases. `overflow: hidden` also creates a Block Formatting Context (BFC), which clears floated children.Shown above the full answer for quick recall.Answer (EN)Image**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: `visible` lets water spill everywhere, `hidden` seals it shut, `scroll` adds permanent drain pipes, `auto` adds pipes only when the tank overflows. - Main difference: `auto` shows scrollbars only when content exceeds the box; `scroll` always renders them. - `overflow: hidden` also triggers a Block Formatting Context (BFC), which wraps floated children automatically. - Decision rule: `hidden` to crop UI cleanly (cards, avatars), `auto` for dynamic content like chat logs or sidebars. ### Quick example ```css /* 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: ```css /* 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: auto` with a `max-height` - Horizontal nav or data table: `overflow-x: auto` for small screens - Body element during modal open: `overflow: hidden` blocks background scroll - Rounded card or avatar: `overflow: hidden` clips 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. ```css .container { overflow: hidden; /* BFC: wraps floated children, no height collapse */ } ``` ### Common mistakes **Forgetting height with `overflow: auto`.** ```css /* 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.** ```css /* 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: auto` on `.modal-body` for scrollable modal content - **TailwindCSS**: `overflow-hidden` on card components in Next.js templates - **Bootstrap**: `.table-responsive` uses `overflow-x: auto` for wide tables on mobile - **VS Code**: sidebar panels combine `overflow: hidden` with 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 ```html <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 ```jsx 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.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.