The Rendering Cost of Dynamic Content
Every time the DOM changes, the browser must recompute styles, layout, and paint. For pages with many interactive widgets—chat feeds, stock tickers, infinite-scroll lists—these recalculations can ripple across the entire document, causing jank and dropped frames.
The CSS contain property tells the browser that a subtree is independent from the rest of the page. This enables the engine to skip global recalculations and treat the element as an isolated island.
Contain Values
The property accepts one or more space-separated keywords:
| Value | Effect |
|---|---|
layout | No external element can affect the layout of this subtree, and vice versa. The element establishes a new formatting context. |
paint | The subtree is clipped to the element’s box. Descendants never render outside its bounds. Enables paint-time 최적화. |
size | The element’s size is determined by its specified width/height, ignoring children. Useful for virtualized containers. |
style | Counter-increment, quotes, and other scoped properties are contained. Less commonly needed. |
strict | Shorthand for layout paint size style — the full containment set. |
content | Shorthand for layout paint style — excludes size so the box can still shrink-wrap its children. |
How Containment Isolates Rendering
Without containment, changing the top of a fixed-position chat widget triggers layout recalculations that propagate up to the root and potentially down through unrelated branches.
.chat-widget {
contain: layout paint size;
width: 320px;
height: 480px;
}
With contain: layout, the browser knows this subtree cannot cause layout shifts outside its box. The Layout step stops at the container boundary. With contain: paint, no child pixels bleed outside the container’s border box, so repaints can be scoped to a smaller dirty rect.
Real-World Use Cases
Third-party embeds — Embedding a Twitter timeline or a map widget introduces unknown DOM mutations. Wrapping them in a contained <div> prevents their internal reflows from slowing down your main content.
<div class="embed-container">
<div id="third-party-widget"></div>
</div>
.embed-container {
contain: content;
width: 100%;
max-width: 600px;
}
Virtual scrolling — Libraries like React-window set explicit dimensions on the viewport container. Adding contain: strict reinforces the sizing contract and lets the browser optimize paint for clipped children.
Animating elements — Continuously animating a UI element (e.g., a loading spinner) triggers per-frame repaints. Containing it isolates those repaints from the rest of the page.
성능 Impact
A typical benchmark on a page with 10,000 DOM nodes shows:
| Scenario | Style recalculation | Layout time |
|---|---|---|
| No containment | ~12 ms | ~8 ms |
contain: content | ~2 ms | ~1 ms |
contain: strict | ~2 ms | <1 ms |
The improvement compounds as the widget count grows. For complex dashboard applications, containment can reduce total frame time by 30–50 %.
Browser Support
contain is supported in all modern browsers:
- Chrome 52+
- Firefox 69+
- Safari 15.4+
- Edge 79+
The content and strict keywords are recognized everywhere the property itself is supported. The style keyword is newer but broadly available.
Caveats
contain: sizerequires explicit dimensions. Without a setwidth/height, the element collapses to 0px. Always pairsizewith defined sizing.- Containment is not a 성능 silver bullet. Over-using it on small elements adds overhead. Apply it to independent, mutation-heavy subtrees.
contain: styleis rarely needed. It scopes counter-increment and list-item markers but does not isolate CSS custom properties.
Summary
CSS containment is a low-cost, high-impact 성능 tool for any page with dynamic content islands. By selectively isolating subtrees, you prevent unnecessary layout and paint work, keeping interactions smooth and frame rates high. Start with contain: content on widgets and embeds, then 프로필 to see the difference.

