contain
Promises the browser that an element’s interior doesn’t affect the rest of the page, so it can limit layout recalculation and painting.
- Initial value
none- Inherited
- No
- Animatable
- no
- Applies to
- all elements, but size, layout, and paint have no effect on plain inline elements or internal table elements (other than cells)
- JavaScript
element.style.contain = "content"
Example
#.feed {
display: grid;
gap: 8px;
}
.feed-item {
contain: content;
padding: 10px 12px;
border-radius: 10px;
background: #18181b;
}<ul class="feed" style="margin: 0; padding: 0; list-style: none;">
<li class="feed-item"><strong>Ania</strong> finished the Flexbox module <small style="color: #a1a1aa;">· 2 min ago</small></li>
<li class="feed-item"><strong>Kuba</strong> already has a 7-day streak <small style="color: #a1a1aa;">· 5 min ago</small></li>
<li class="feed-item"><strong>Ola</strong> joined the Python world <small style="color: #a1a1aa;">· 12 min ago</small></li>
</ul>Each entry is walled off from the rest. When something changes in one of them that doesn’t affect its size, for example a like counter, the browser can recalculate just that entry instead of the whole page. content doesn’t require set dimensions, so the entries still fit their height to the content.
Definition and usage
#The contain property lets you wall off a piece of the page from the rest. You declare that whatever happens inside the element won’t affect its surroundings, and the browser can then recalculate and paint just that piece. It’s handy for long lists, widgets, and panels that change often.
The kinds of containment can be combined: size (the element’s size doesn’t depend on its content), inline-size (the same, but only for the inline size), layout (the layout inside doesn’t affect the outside), paint (descendants don’t paint outside the element), and style (CSS counters changed inside don’t affect the outside). The content shorthand means layout paint style, and strict is all three of those together with size.
Every kind has visible side effects. With layout and paint, the element becomes a containing block for descendants with position: absolute and fixed, and creates a new stacking context. paint also clips anything that sticks out, similar to overflow: clip. With size, an element with no given dimensions is measured as if it were empty, so its height drops to zero.
You rarely set contain by hand day to day, since other properties often do it for you: container-type turns on size containment, and content-visibility: auto turns on containment and additionally skips rendering content that’s off-screen.
Syntax
#contain: none | strict | content | [ [ size | inline-size ] || layout || style || paint ];Values
#- No containment. The badge positions itself relative to the outer frame, since that’s the one with
position: relative. - The card becomes a containing block, so the badge jumps to its corner. Nothing gets clipped.
- The badge also lands in the card’s corner, but the part that sticks out past the card gets cut off.
- The card’s height stops depending on its content. Without a set size, the card collapses to just its padding, and the text spills out below.
layout paint style
The safest combination: the card isolates layout and painting, but still fits its height to the content. It looks the same aspaint.size layout paint style
Everything at once. A card with no dimensions collapses, andpaintclips all the content, leaving an empty bar. Only use this with a fixed size.
Values in practice
#none
position: relative..demo { contain: none; }layout
.demo { contain: layout; }paint
.demo { contain: paint; }size
.demo { contain: size; }content
paint..demo { contain: content; }strict
paint clips all the content, leaving an empty bar. Only use this with a fixed size..demo { contain: strict; }Browser support
#Widely available · since 2022
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#contain: contentis a reasonable choice for independent widgets and items in long lists. It needs no dimensions and rarely breaks anything, as long as nothing has to stick out past the element.- Use
sizeandstrictonly with fixed dimensions, or together withcontain-intrinsic-size, otherwise the element collapses to zero. - If a
position: fixedwindow stops covering the whole screen after you addcontain, that’s the effect of the new containing block. Move the window outside the contained element, or use a<dialog>opened withshowModal().
Related entries
#- content-visibilityLets the browser skip rendering content that isn’t visible, speeding up long pages.
- container-typeTurns an element into a container that @container rules can query for its size. Also covers container-name and the container shorthand.
- overflowDecides what happens to content that doesn’t fit in an element.
- positionChooses how an element is positioned: in the flow, relative, absolute, fixed, or sticky.
- z-indexDetermines which element sits on top when elements overlap.
Spotted a mistake or missing an example? Write to us.