Containment & container queries
The properties that isolate part of the page from the rest, so the browser can skip work on it; give skipped content a placeholder size; make an element a container that @container rules can query; and hint at changes to come. The sizing properties that containment overrides are under Box model.
Containment
contain
Promises the browser that an element's subtree is independent of the rest of the page in one or more ways, so it can lay out, paint or style that part on its own and skip it when nothing inside has changed.
| Syntax | none | strict | content | [ [size | inline-size] || layout || style || paint ] |
|---|---|
| Initial | none |
| Applies to | All elements. Size, layout and paint containment have no effect on non-atomic inline boxes and internal table or ruby boxes; style containment always applies. |
| Inherited | No |
| Animation | Not animatable |
| Support | Chrome 52 · Firefox 69 · Safari 15.4inline-size: Chrome 105 · Firefox 101 · Safari 16 |
| Spec | css-contain-2 |
| Value | Effect |
|---|---|
size | The element is sized as if it had no content, so its size must come from elsewhere (width, height, contain-intrinsic-size). |
inline-size | Like size, but in the inline axis only. |
layout | Nothing inside affects layout outside, and the reverse. The element becomes a containing block for positioned and fixed descendants and starts a new stacking context. |
paint | Descendants are clipped to the padding box and are not painted when the element is off-screen. |
style | Counters and open-quote/close-quote inside do not affect the rest of the page. |
strict | Same as size layout paint style. |
content | Same as layout paint style: every type except size. |
.widget { contain: content; }
content-visibility
Lets the browser skip rendering an element's contents. With auto the contents are only laid out and painted when the element is near the viewport; with hidden they are never rendered, but unlike display: none the browser can keep their rendering state cached.
| Syntax | visible | auto | hidden |
|---|---|
| Initial | visible |
| Applies to | Elements for which size containment can apply |
| Inherited | No |
| Animation | Discrete, with special rules for transitions to and from hidden |
| Support | Chrome 85 · Firefox 125 · Safari 18 |
| Spec | css-contain-2 |
auto turns on layout, style and paint containment, plus size containment while the contents are skipped. Skipped contents stay in the document, so they can still be found with find-in-page and reached by keyboard focus. Give the element a placeholder size with contain-intrinsic-size so the scrollbar does not jump as sections render.
article > section {
content-visibility: auto;
contain-intrinsic-size: auto 40rem;
}
Intrinsic size placeholders
contain-intrinsic-size
Shorthand for contain-intrinsic-width and contain-intrinsic-height: the size an element with size containment is given, as if its contents were that size. One value sets both axes; two set width then height.
| Syntax | [ auto? [ none | <length [0,∞]> ] ]{1,2} |
|---|---|
| Initial | See individual properties |
| Applies to | See individual properties |
| Inherited | See individual properties |
| Percentages | See individual properties |
| Animation | See individual properties |
| Support | Chrome 83 · Firefox 107 · Safari 17 |
| Spec | css-sizing-4 |
With auto, once the element has been rendered the browser remembers its real size and uses that instead of the length while its contents are skipped.
contain-intrinsic-width, contain-intrinsic-height, contain-intrinsic-block-size, contain-intrinsic-inline-size
The placeholder size in one axis: physical for -width and -height, flow-relative for -block-size and -inline-size. none means the element is sized as if empty in that axis.
| Syntax | auto? [ none | <length [0,∞]> ] |
|---|---|
| Initial | none |
| Applies to | Elements with size containment |
| Inherited | No |
| Animation | By computed value type |
| Support | Chrome 95 · Firefox 107 · Safari 17 |
| Spec | css-sizing-4 |
Query containers
container
Shorthand for container-name and, after a slash, container-type.
| Syntax | <'container-name'> [ / <'container-type'> ]? |
|---|---|
| Initial | See individual properties |
| Applies to | See individual properties |
| Inherited | See individual properties |
| Percentages | See individual properties |
| Animation | See individual properties |
| Support | Chrome 105 · Firefox 110 · Safari 16 |
| Spec | css-conditional-5 |
.cards { container: cards / inline-size; }
@container cards (width > 40rem) {
.card { grid-template-columns: 1fr 2fr; }
}
container-name
One or more names for a query container, so an @container rule can target it by name instead of the nearest suitable ancestor.
| Syntax | none | <custom-ident>+ |
|---|---|
| Initial | none |
| Applies to | All elements |
| Inherited | No |
| Animation | Not animatable |
| Support | Chrome 105 · Firefox 110 · Safari 16 |
| Spec | css-conditional-5 |
container-type
Makes an element a query container for size queries, scroll-state queries or both.
| Syntax | normal | [ [ size | inline-size ] || scroll-state ] |
|---|---|
| Initial | normal |
| Applies to | All elements |
| Inherited | No |
| Animation | Not animatable |
| Support | Chrome 105 · Firefox 110 · Safari 16scroll-state: Chrome 133 · Firefox no · Safari no |
| Spec | css-conditional-5 |
| Value | Effect |
|---|---|
normal | Not a container for size queries. Every element can still be queried with style queries. |
inline-size | Size queries on the inline axis. Applies inline-size containment, so the element's width cannot depend on its contents. |
size | Size queries on both axes. Applies size containment, so the element needs a height from elsewhere. |
scroll-state | Queries on the element's scroll state, such as whether it is stuck, snapped or scrollable. |
inline-size is the usual choice. Because of the containment, a container cannot size itself from its children in the queried axis; give it a width from its parent layout.
Performance hints
will-change
Tells the browser which properties of an element are about to change, so it can prepare, for example by moving the element to its own compositing layer. An <animateable-feature> is scroll-position, contents or a property name.
| Syntax | auto | <animateable-feature># |
|---|---|
| Initial | auto |
| Applies to | All elements |
| Inherited | No |
| Animation | Not animatable |
| Support | Chrome 36 · Firefox 36 · Safari 9.1 |
| Spec | css-will-change-1 |
Naming a property that would create a stacking context or containing block, such as opacity or transform, makes the element create one straight away. Use it sparingly, on elements that really are about to animate, since each hint costs memory.
.drawer { will-change: transform; }