Overflow is one of those CSS topics that feels boring… right up until a dropdown gets chopped in half, a code block creates a sideways-scroll apocalypse, or your “perfect” card layout suddenly grows a mysterious second scrollbar. Let’s fix that forever.

What CSS overflow means

The overflow family of properties controls what happens when a box’s content is bigger than the box itself.

  • Overflow happens when content can’t fit in the element’s content box.
  • You usually need a constraint to see overflow: a width, a height, a max-height, etc.
  • Overflow is about the element’s own content, not its position on the page.

In other words: no constraint, no overflow drama (most of the time).

overflow:
.box {
  overflow: visible;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.box {
  width: min(520px, 100%);
  height: 160px;
  border: 3px solid #111;
  border-radius: 16px;
  background: #f6f6f6;
  padding: 12px;
}

.box p {
  margin: 0 0 10px;
}

.big {
  width: 740px;
  padding: 12px;
  border: 2px dashed #111;
  border-radius: 12px;
  background: #fff;
}

.note {
  font-size: 14px;
  opacity: 0.85;
}
  

Try switching overflow with the radios above.

I am wider than the box, and I’m also tall enough to require scrolling.

Extra lines. Extra lines. Extra lines.
Extra lines. Extra lines. Extra lines.
Extra lines. Extra lines. Extra lines.

Tip: overflow affects both axes unless you override them with overflow-x / overflow-y.

CSS overflow property and options

Here are the options you’ll use 99% of the time:

  • visible (default): content can paint outside the box.
  • hidden: content is clipped and not scrollable by the user.
  • scroll: always show scrollbars (even if not needed).
  • auto: show scrollbars only when needed.
  • clip: clip the content like hidden, but without creating a scroll container.

That last one is sneaky and useful. We’ll cover it properly soon.

CSS overflow scroll vs CSS overflow auto

scroll and auto feel similar because both can scroll. The difference is simple:

  • overflow: scroll; forces scrollbars to appear, even if the content fits.
  • overflow: auto; shows scrollbars only when the content actually overflows.

Use auto most of the time. Use scroll when you want stable layout (no “jump” when the scrollbar appears).

.panel {
  overflow: auto;
}
  
.panel {
  overflow: scroll;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.panel {
  width: min(560px, 100%);
  height: 140px;
  border: 3px solid #111;
  border-radius: 16px;
  background: #f6f6f6;
  padding: 12px;
}

.content {
  display: grid;
  gap: 10px;
  min-width: 720px;
}

.card {
  border: 2px solid #111;
  border-radius: 12px;
  padding: 10px;
  background: #fff;
}

.hint {
  font-size: 14px;
  opacity: 0.85;
}
  
Row 1 — wide content forces horizontal overflow.
Row 2 — add a few rows and you get vertical overflow too.
Row 3 — hello, scrollbars.
Row 4 — still here.
Row 5 — still scrolling.

In the scroll version, scrollbars can appear even when they’re not needed. In the auto version, they appear only when overflow actually happens.

CSS overflow-x and overflow-y

Sometimes you only want scrolling (or clipping) in one direction:

  • overflow-x controls left/right overflow.
  • overflow-y controls top/bottom overflow.

A very common pattern: allow horizontal scrolling for code blocks, but avoid vertical scrolling.

.scroller {
  overflow-x: auto;
  overflow-y: hidden;
}
  
.scroller {
  overflow-x: hidden;
  overflow-y: auto;
}
  
.scroller {
  overflow-x: auto;
  overflow-y: auto;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.scroller {
  width: min(600px, 100%);
  height: 150px;
  border: 3px solid #111;
  border-radius: 16px;
  background: #f6f6f6;
  padding: 12px;
}

.grid {
  display: grid;
  gap: 10px;
  min-width: 760px;
}

.item {
  border: 2px solid #111;
  border-radius: 12px;
  background: #fff;
  padding: 10px;
}

.tip {
  font-size: 14px;
  opacity: 0.85;
}
  
Wide item — forces horizontal overflow.
Another item — adds vertical overflow as well.
One more — now you can choose which axis scrolls.
And another — because overflow loves company.

If you only want horizontal scrolling (like for long code lines), start with overflow-x: auto; and keep overflow-y under control.

CSS overflow hidden

overflow: hidden; is the “nope” button: content outside the box is clipped and the user can’t scroll to it.

Common uses:

  • Crop images (often paired with border-radius).
  • Hide decorative overflow (like blobs, glows, or offscreen elements).
  • Create clean UI masks for animations.

But be careful: hidden can also hide focus outlines, dropdown menus, and tooltips. If something is “randomly disappearing,” this is a prime suspect.

.crop {
  overflow: hidden;
}
  
.crop {
  overflow: visible;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.crop {
  width: min(520px, 100%);
  border: 3px solid #111;
  border-radius: 18px;
  background: #f6f6f6;
  padding: 12px;
}

.hero {
  width: 680px;
  height: 180px;
  border-radius: 16px;
  border: 2px solid #111;
  background: linear-gradient(120deg, #03045e 0%, #0077b6 55%, #90e0ef 100%);
  display: grid;
  place-items: center;
  font-weight: 700;
  letter-spacing: 0.4px;
}

.hero span {
  background: #fff;
  border: 2px solid #111;
  border-radius: 999px;
  padding: 8px 12px;
}

.caption {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}
  
Wide “banner” inside a smaller container

Switch between hidden and visible to see how the overflow is clipped (or not).

CSS overflow clip

overflow: clip; also clips overflow, but it behaves differently from hidden in an important way:

  • hidden creates a scroll container (even if you can’t scroll it as a user).
  • clip clips without creating a scroll container.

Why does that matter? Because “being a scroll container” can affect things like sticky positioning (using position: sticky;), scroll-based APIs, and sometimes how browsers optimize rendering. If you only want to clip (and not accidentally turn the element into a scroll container), clip is a great choice.

Overflow:clip can be a lifesaver in particular when you are using position: sticky;.

.stage {
  overflow: hidden;
}
  
.stage {
  overflow: clip;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.viewport {
  width: min(640px, 100%);
  height: 260px;
  border: 3px solid #111;
  border-radius: 18px;
  background: #f6f6f6;
  overflow: auto;
  padding: 12px;
}

.stage {
  border: 2px solid #111;
  border-radius: 16px;
  background: #fff;
  padding: 12px;
}

.sticky {
  position: sticky;
  top: 0;
  z-index: 2;
  border: 2px solid #111;
  border-radius: 14px;
  background: #f6f6f6;
  padding: 10px 12px;
  font-weight: 800;
}

.sticky small {
  display: block;
  font-weight: 600;
  opacity: 0.8;
  margin-top: 4px;
}

.list {
  display: grid;
  gap: 10px;
  margin-top: 12px;
}

.item {
  border: 2px dashed #111;
  border-radius: 14px;
  padding: 12px;
  background: #fff;
  line-height: 1.35;
}

.hint {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}
  
Sticky header Scroll this box. with hidden, sticky “breaks”.
Item 1 — Keep scrolling.
Item 2 — Sticky should stay at the top while content moves.
Item 3 — This is the classic “scrollable panel” setup.
Item 4 — More content, more scroll.
Item 5 — We need enough height to make the effect obvious.
Item 6 — Almost there.
Item 7 — Keep going.
Item 8 — The sticky header should be your “anchor”.
Item 9 — Scroll a bit more.
Item 10 — Still scrolling.
Item 11 — Nearly at the end.
Item 12 — Done.

Switch snippets and scroll inside the bordered panel: overflow: hidden makes .stage a scroll container, so the sticky element stops sticking to the outer scroller. overflow: clip clips without creating a scroll container, so sticky keeps working.

Learn more about position: sticky; in the CSS Position Sticky Interactive Tutorial.

Overflow + border-radius image crop

This is one of the most common (and most satisfying) uses of overflow: cropping an image to a rounded shape.

The basic idea:

  • The container gets the shape (with border-radius).
  • overflow: hidden; ensures anything outside that rounded shape is clipped.
  • The image is sized with width: 100% and typically object-fit: cover so it fills the crop without distortion.

Without overflow: hidden, the image can visibly “poke out” past the rounded corners (especially if the image is larger than the container).

.thumb {
  overflow: hidden;
}
  
.thumb {
  overflow: visible;
}
  
.thumb {
  overflow: clip;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.thumb {
  width: min(560px, 100%);
  aspect-ratio: 16 / 9;
  border: 3px solid #111;
  border-radius: 22px;
  background: #f6f6f6;
}

.thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.caption {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}

.hint {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}
  
Random placeholder image from Picsum

Switch snippets: hidden and clip crop to the rounded corners, while visible allows the image to paint outside the rounded shape.

Image crop with a “zoom on hover” effect

Once you’re cropping correctly, you can safely scale the image on hover without it overflowing the rounded container. This is a super common card/thumbnail interaction.

.thumb {
  overflow: hidden;
}
.thumb img {
  transform: scale(1);
  transition: transform 250ms ease;
}

.thumb:hover img {
transform: scale(1.1);
} 
.thumb {
  overflow: visible;
}
.thumb img {
  transform: scale(1);
  transition: transform 250ms ease;
}

.thumb:hover img {
transform: scale(1.1);
} 
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.thumb {
  width: min(520px, 100%);
  aspect-ratio: 3 / 2;
  border: 3px solid #111;
  border-radius: 22px;
  background: #f6f6f6;
}

.thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.note {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}
  
Random placeholder image from Picsum

Because the container has overflow: hidden, the zoom stays neatly inside the rounded crop.

Scroll snapping + overflow for carousel-like UI patterns

Scroll snapping is how you get that “carousel feel” using pure CSS (plus native scrolling). The secret sauce is:

  • A scroll container: usually overflow-x: auto
  • scroll-snap-type on the container
  • scroll-snap-align on each item

This works great for horizontal card rows, feature panels, and “swipeable” sections on touch devices.

.carousel {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

.slide {
scroll-snap-align: start;
} 
.carousel {
  overflow-x: auto;
  scroll-snap-type: x proximity;
}

.slide {
  scroll-snap-align: start;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.carousel {
  width: min(740px, 100%);
  border: 3px solid #111;
  border-radius: 18px;
  background: #f6f6f6;
  padding: 12px;
  display: flex;
  gap: 12px;
  scroll-padding-left: 12px;
}

.slide {
  flex: 0 0 78%;
  border: 2px solid #111;
  border-radius: 16px;
  background: #fff;
  padding: 14px;
  min-height: 160px;
  display: grid;
  gap: 10px;
}

.badge {
  display: inline-block;
  border: 2px solid #111;
  border-radius: 999px;
  padding: 4px 10px;
  width: fit-content;
  background: #f6f6f6;
  font-weight: 700;
}

.slide p {
  margin: 0;
  line-height: 1.45;
}

.hint {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}
  

Use scroll-snap-type: x mandatory for a stronger “carousel” feel, or x proximity for a more relaxed snap.

Snap centering cards

If you want each card to snap into the center instead of the left edge, use scroll-snap-align: center. Pair it with scroll-padding so the centered alignment feels intentional.

.carousel {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: 0 18px;
}

.slide {
scroll-snap-align: center;
} 
.carousel {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding: 0 18px;
}

.slide {
  scroll-snap-align: start;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.carousel {
  width: min(740px, 100%);
  border: 3px solid #111;
  border-radius: 18px;
  background: #f6f6f6;
  padding: 12px;
  display: flex;
  gap: 12px;
}

.slide {
  flex: 0 0 62%;
  border: 2px solid #111;
  border-radius: 16px;
  background: #fff;
  padding: 14px;
  min-height: 140px;
  display: grid;
  gap: 8px;
}

.kicker {
  margin: 0;
  font-weight: 700;
}

.copy {
  margin: 0;
  line-height: 1.45;
}

.tip {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}
  

For center snapping, use scroll-snap-align: center on the items and scroll-padding on the container.

Pro tips for scroll snapping + overflow

  • Use overflow-x: auto, not scroll, unless you intentionally want scrollbars always visible.
  • Add gaps with gap on the flex container. It’s clean and reliable.
  • Use scroll-padding to control where the snap “rests” visually.
  • If snapping feels too aggressive, switch from mandatory to proximity.

CSS overflow wrap

This section is a tiny terminology gotcha: “overflow wrap” usually refers to the overflow-wrap property, not the overflow property.

overflow-wrap controls how the browser breaks very long words (or URLs) that would otherwise blow up your layout.

  • overflow-wrap: normal; keeps normal word-breaking behavior.
  • overflow-wrap: anywhere; allows breaking anywhere if needed.
  • overflow-wrap: break-word; is widely used to prevent long words from overflowing.

If you’ve ever seen a single very-long-URL stretch a card to 2000px wide, this is your fix.

.textbox {
  overflow-wrap: normal;
}
  
.textbox {
  overflow-wrap: break-word;
}
  
.textbox {
  overflow-wrap: anywhere;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.textbox {
  width: min(520px, 100%);
  border: 3px solid #111;
  border-radius: 16px;
  background: #f6f6f6;
  padding: 12px;
}

.textbox p {
  margin: 0;
  border: 2px solid #111;
  border-radius: 12px;
  background: #fff;
  padding: 10px;
  line-height: 1.4;
}

.small {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}
  

Here is a very long “word” that doesn’t want to wrap: SuperLongUnbrokenTokenThatKeepsGoingAndGoingAndGoingAndGoingAndGoing and a long URL: https://example.com/this/is/a/very/very/very/very/very/very/long/path

Use overflow-wrap to prevent long strings from breaking your layout.

CSS overflow ellipsis

Ellipsis is another common wording gotcha. There’s no overflow: ellipsis. Instead, the classic single-line ellipsis uses:

  • white-space: nowrap;
  • overflow: hidden;
  • text-overflow: ellipsis;

All three are required for the “…” to appear in the common single-line case.

Single-line ellipsis

.title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
  
.title {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.card {
  width: min(520px, 100%);
  border: 3px solid #111;
  border-radius: 16px;
  background: #f6f6f6;
  padding: 12px;
  display: grid;
  gap: 10px;
}

.title {
  border: 2px solid #111;
  border-radius: 12px;
  padding: 10px;
  background: #fff;
  font-weight: 700;
}

.meta {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}
  
A very long title that should not wrap because we want a clean single-line card header, even if it keeps going forever

Switch snippets to compare “ellipsis” vs normal wrapping.

Multi-line ellipsis with line clamp

Multi-line truncation is a bit different. A popular approach uses -webkit-line-clamp (commonly supported) with a special box display model. It’s not as “pure and simple” as the single-line version, but it’s widely used in real UI.

.excerpt {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}
  
.excerpt {
  display: block;
  overflow: visible;
}
  
*,
::before,
::after {
  box-sizing: border-box;
}

.wrap {
  max-width: 980px;
  padding: 18px;
  display: grid;
  gap: 12px;
  font-family: system-ui, Arial, sans-serif;
}

.card {
  width: min(560px, 100%);
  border: 3px solid #111;
  border-radius: 16px;
  background: #f6f6f6;
  padding: 12px;
  display: grid;
  gap: 10px;
}

.excerpt {
  border: 2px solid #111;
  border-radius: 12px;
  padding: 0 10px;
  background: #fff;
  line-height: 1.5;
}

.small {
  font-size: 14px;
  opacity: 0.85;
  margin: 0;
}
  
This is a longer chunk of text meant to behave like a teaser or preview. With line clamping enabled, it will show only a few lines and then truncate. Without clamping, it will expand normally and show the full content. Add a few more lines so the truncation is obvious and easy to see in the preview.

Multi-line truncation often uses -webkit-line-clamp plus overflow: hidden.

Learn more in the CSS Ellipsis Interactive Tutorial.

Common overflow bugs and fixes

“Overflow isn’t working” (no size constraint)

If an element can grow to fit its content, you won’t see overflow. Add a constraint like height, max-height, or a width that can’t expand.

Double scrollbars

Double scrollbars usually means you made a scroll container inside another scroll container. Decide which element should scroll, then remove scrolling from the other (often by setting overflow: visible or adjusting heights).

Unexpected horizontal scrolling

This is often caused by long unbroken content (URLs, code, long tokens). Try:

  • overflow-wrap: break-word; or anywhere for text content.
  • overflow-x: auto; for code blocks that you want to scroll horizontally.

Hidden clips focus rings and menus

overflow: hidden can clip focus outlines, dropdowns, tooltips, and popovers. If an interactive thing “disappears,” inspect parents for overflow clipping and consider moving the popover outside the clipped container.

Quick reference

  • Default behavior: overflow: visible
  • Scroll only when needed: overflow: auto
  • Force scrollbars: overflow: scroll
  • Clip content: overflow: hidden or overflow: clip
  • Control axes: overflow-x and overflow-y
  • Wrap long words: overflow-wrap: break-word / anywhere
  • Single-line ellipsis: white-space: nowrap + overflow: hidden + text-overflow: ellipsis

CSS Overflow Conclusion

Mastering CSS overflow is key to building robust, user-friendly layouts. Whether you’re creating scrollable panels, cropping images, or handling text truncation, understanding how overflow works will help you avoid common pitfalls and create polished interfaces. Remember to choose the right overflow behavior for your specific use case, and don’t forget about the powerful tools like overflow-wrap and scroll snapping that can take your designs to the next level. Happy coding!