Website Spec
Performance Optional Updated 2026-05-29

CSS containment

Use `contain: layout paint style` (or the `contain: content` shorthand) to tell the browser that an element's internals cannot affect the rest of the page, so reflow and repaint stay isolated to that subtree.

What it is

The contain CSS property is a hint to the rendering engine: the element’s subtree is independent of the rest of the document, so the browser can scope layout, paint, and style work to it. Four containment types compose:

  • layout — descendants do not affect the layout of anything outside the element, and vice versa.
  • paint — descendants are clipped to the element’s box; nothing paints outside it.
  • style — counters and quotes inside the element do not leak out.
  • size — the element’s own size is computed without consulting its children. Requires an explicit size or contain-intrinsic-size, otherwise the box collapses.

The shorthand contain: content is equivalent to layout paint style — deliberately excluding size, because most components do not have a known intrinsic size. The stricter contain: strict adds size on top.

Why it matters

Browsers optimise rendering by computing layout, paint, and style for the smallest possible scope. Without containment, a class change deep inside a card can force the browser to recompute the layout of the surrounding page, because, in principle, an element’s children can affect ancestors (think percentage heights, intrinsic sizing, or position: absolute escaping). Containment lets you assert that they cannot, so the engine can skip work it would otherwise have to do defensively.

The payoff is largest on pages with many independent components — feeds, grids, dashboards, long article comments — where a single interaction would otherwise invalidate a chunk of the document.

How to implement

Apply contain: content to self-enclosed components — cards, sidebars, widgets, repeated list items — where children stay within the box and have predictable sizing:

.card,
.sidebar-widget,
.feed-item {
  contain: content;
}

For off-screen sections, pair with content-visibility: auto so the browser can skip rendering entirely until the section approaches the viewport:

article > section {
  content-visibility: auto;
  contain-intrinsic-size: 0 800px;
}

Common mistakes

  • Applying contain: size without contain-intrinsic-size. The box collapses to zero in the contained axis, because children no longer contribute to its size.
  • Containing elements whose children must overflow visually. Tooltips, dropdown menus, and floating labels get clipped by paint containment.
  • Reaching for contain: strict at the page level. Sticky positioning, fixed children, and anchor scrolling break when their containing block is unexpectedly isolated.
  • Treating containment as free. There is a small cost to maintaining the boundary; apply it where you have measured a benefit, not as a reflex.

Verification

  • Chrome DevTools → Performance panel. Record an interaction before and after; recalc-style and layout costs on the contained subtrees should drop.
  • DevTools → Rendering → “Paint flashing” and “Layer borders”. Confirms the isolation is real — paint should not extend past contained boxes.
  • Test scroll and interaction on long pages on a mid-range device. If frame times do not improve, the bottleneck was elsewhere; revert.

Related topics

Sources & further reading

Search
esc close navigate open