Articles /

layout

Overflow: visible, hidden, scroll, clip, auto

Overflow controls what happens when content exceeds its container. Each value has side effects worth understanding.

The five overflow values

The overflow property determines how content that overflows an element's box is handled. Here are all the values:

/* Default — content spills out visibly */
.box { overflow: visible; }

/* Clips content, creates scroll container (scrollable via JS) */
.box { overflow: hidden; }

/* Always shows scrollbars */
.box { overflow: scroll; }

/* Shows scrollbars only when needed */
.box { overflow: auto; }

/* Clips content without creating a scroll container */
.box { overflow: clip; }

The key distinction: hidden creates a scroll container (even though no scrollbar is shown), while clip does not. This has major implications for sticky positioning and paint containment.

clip vs hidden

The overflow: clip value was introduced specifically to address the side effects of overflow: hidden. Here's why it matters:

/* hidden: creates a scroll container */
/* This BREAKS position: sticky on descendants */
.parent {
  overflow: hidden;
}

/* clip: no scroll container created */
/* Sticky positioning still works inside */
.parent {
  overflow: clip;
}

/* clip can be applied per-axis */
.parent {
  overflow-x: clip;
  overflow-y: visible;
}
Use overflow: clip instead of overflow: hidden whenever you need to clip content but don't want to break sticky positioning or create an unwanted scroll container.

Per-axis overflow

You can set overflow independently for each axis with overflow-x and overflow-y. However, there's a catch: if one axis is set to visible and the other to anything except visible or clip, the visible value is treated as auto:

/* This does NOT work as expected */
.container {
  overflow-x: hidden;
  overflow-y: visible;
  /* visible becomes auto — you get a vertical scrollbar */
}

/* Use clip to truly clip one axis */
.container {
  overflow-x: clip;
  overflow-y: visible;
  /* This works — clips horizontally, visible vertically */
}

Text overflow and truncation

The text-overflow property controls how clipped inline text is signaled to the user. It requires both overflow: hidden and white-space: nowrap:

/* Single-line truncation */
.truncate {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Multi-line truncation with line-clamp */
.clamp-3 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

The line-clamp shorthand property is gaining wider support and will eventually replace the -webkit- prefixed version.

Scrollbar styling

Modern CSS offers two approaches to scrollbar customization: the standards-track scrollbar-width and scrollbar-color, and the WebKit-prefixed pseudo-elements:

/* Standards-track (Firefox, Chrome 121+) */
.scrollable {
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: oklch(0.5 0 0) oklch(0.2 0 0);
  /* thumb-color   track-color */
}

/* Hide scrollbar but keep scrollable */
.scrollable-hidden {
  overflow: auto;
  scrollbar-width: none;
}
Prefer scrollbar-width and scrollbar-color over ::-webkit-scrollbar pseudo-elements. The standards-track properties are supported in all major browsers.

Overflow and stacking contexts

Any value other than visible or clip establishes a scroll container, which affects layout in several ways:

  • Margins of child elements no longer collapse through the container boundary.
  • The element becomes a containing block for absolutely positioned descendants.
  • Sticky positioning uses this element as its scrollport instead of the viewport.
  • The element gets a block formatting context, clearing floats automatically.