What Is CSS Containment and How Can I Use It? – CSS Wizardry
Arrange a Masterclass
2 April, 2026
What Is CSS Containment and How Can I Use It?
Written by Harry Roberts on CSS Wizardry .
Table of Contents
Independent writing is brought to you via my wonderful<br>Supporters.
Why Containment Exists
Meet the contain Property
Layout Containment
Paint Containment
Size Containment
Style Containment
Special Values: content and strict
contain: content
contain: strict
Containment in the Real World
OpenTable’s Mobile Drawer
Other Good Candidates
content-visibility and contain-intrinsic-size
Skipping Work with content-visibility
Accessibility and Script Considerations
Caveats, Gotchas, and Things to Watch for
Zero-Sized Boxes
Unexpected Clipping
Stacking Contexts Everywhere
Interaction with Container Queries
When to Use Containment
Good Candidates
Use With Care
Probably Avoid
Closing Thoughts
Continuing my work on web performance for design systems, I want to look at<br>a woefully underused CSS feature called<br>containment.<br>I fear it’s underused because there isn’t much written about it, so this piece<br>aims to be the post I wish I’d been able to read a few years ago. Hopefully it<br>demystifies things a little for you, too.
Modern UIs are busy places. A single page might contain a fixed header, an<br>infinite scroll feed, a sticky cart summary, and a few different third-party<br>widgets stuck around the edges. Every time something changes, the browser needs<br>to decide how much of that page it has to re-think: styles, layout, painting,<br>compositing, and so on.
Out of the box, the browser needs to be cautious. If it cannot be sure that<br>a change is local, it behaves as if almost anything might have moved, forcing it<br>to touch more of the page than is strictly necessary. While this is safe, it’s<br>not always cheap.
CSS containment is a way of telling the browser where the boundaries really are.<br>You use it to say this bit of the DOM is independent of the rest; you can<br>treat it as a self-contained island. In return, the browser is free to skip<br>work outside those islands when things change.
In this post, we’ll take a look at what CSS containment actually is, what each<br>contain value does, and how to use it confidently on real projects without<br>creating hard-to-debug side effects. We’ll also look at my most favourite<br>real-world example of just how effective containment can be. Let’s go!
Get in touch
Need Some Help?<br>I help companies find and fix site-speed issues. Performance audits , training , consultancy , and more.
Why Containment Exists
To understand containment, you don’t need to memorise the entire rendering<br>pipeline, but you do need a rough mental model of where the work goes.
When something changes in the DOM, a browser typically has to:
recalculate styles for affected elements,
recalculate layout (sizes and positions),
repaint the pixels that changed, and
re-composite layers on screen.
The expensive part is often how far those changes spread. A small change in<br>one part of the tree can invalidate layout or painting in other parts—or even<br>the whole document—and the browser cannot always know that the effect is local.<br>That is why relatively simple operations on a large application can feel<br>sluggish: the browser is having to think about the whole world.
Containment is a promise that a given subtree is isolated:
changes inside it will not influence layout or paint outside it, and
in some cases, its own size does not depend on its children.
Once you make that promise, the browser can exploit it. For example:
it can avoid relayout of the rest of the page when something changes inside<br>a contained widget, or
it can skip painting descendants of an off-screen container entirely.
All of that reduces work on the main thread, which is exactly what we want when<br>we are trying to keep interactions snappy (think Interaction to Next<br>Paint).
Meet the contain Property
The main lever you’ll pull is the contain property:
.card {<br>contain: content;
At a high level, contain lets you assert different kinds of independence for<br>an element and its subtree. There are four basic types of containment:
layout
paint
size
style
You can specify them individually or in combinations:
.card {<br>contain: layout paint;
On top of those, there are a couple of shorthand values:
content: shorthand for layout paint style.
strict: shorthand for size layout paint style.
There is also inline-size, which is a more targeted form of size<br>containment—we don’t really need to give it much more attention than that.
Let’s go through each of these in turn.
You might also like…
Preparing Vim for Apple’s Touch Bar<br>(2017)
Layout Containment
contain: layout tells the browser that the internal layout of the<br>element is completely independent of the rest of the page.
.card {<br>contain: layout;
In practice, that means:
layout calculations for descendants of .card do not affect layout<br>outside of .card,
the .card establishes its own...