container-type
Turns an element into a container that @container rules can query for its size. Also covers container-name and the container shorthand.
- Initial value
normal- Inherited
- No
- Animatable
- no
- Applies to
- all elements
- JavaScript
element.style.containerType = "inline-size"
Example
#.widget {
container: stat / inline-size;
}
.widget .chart {
display: none;
}
@container stat (width >= 260px) {
.widget .chart {
display: flex;
}
}<style>
.stats { display: flex; flex-wrap: wrap; align-items: start; gap: 10px; }
.narrow { flex: 0 0 160px; }
.wide { flex: 1 1 280px; }
.stat { padding: 12px; border: 1px solid #27272a; border-radius: 12px; background: #18181b; }
.stat small { color: #a1a1aa; }
.stat strong { display: block; font-size: 22px; line-height: 1.2; }
.chart { align-items: end; gap: 4px; height: 44px; margin-top: 10px; }
.chart span { flex: 1; border-radius: 3px 3px 0 0; background: #7c3aed; }
</style>
<div class="stats">
<div class="widget narrow">
<div class="stat">
<small>Streak</small>
<strong>12 days</strong>
<div class="chart"><span style="height: 40%"></span><span style="height: 70%"></span><span style="height: 55%"></span><span style="height: 90%"></span><span style="height: 100%"></span></div>
</div>
</div>
<div class="widget wide">
<div class="stat">
<small>EXP this week</small>
<strong>1240</strong>
<div class="chart"><span style="height: 30%"></span><span style="height: 65%"></span><span style="height: 45%"></span><span style="height: 80%"></span><span style="height: 60%"></span><span style="height: 95%"></span><span style="height: 75%"></span></div>
</div>
</div>
</div>Both widgets share the same code. The chart only shows up in a container that’s at least 260px wide, so the narrow column shows just the number.
Definition and usage
#The container-type property marks an element as a container for @container queries. Without it, @container rules have nothing to measure and simply never activate. The most common value is inline-size: the container then exposes its size along the inline axis, which in horizontal text means its width, and components inside it can adapt to that.
This convenience comes at a price. The size you can query can’t depend on the content, otherwise styles and size would chase each other in a loop. With inline-size, the container’s width stops being driven by its content, so an element that would normally size itself to its content, such as inline-block or float without a set width, can shrink to zero. With size, this applies to both dimensions, so you have to set the height yourself.
The container-name property gives the container a name, or even several names separated by spaces. The query @container name (…) then targets the nearest ancestor with that name, and a query without a name targets the nearest ancestor that is a container at all. The container: name / type shorthand sets both properties at once, for example container: sidebar / inline-size.
The queries themselves, the cqi units, and ready-made component patterns are covered in the @container entry. Here we focus on how to define a container and what to expect from it.
Syntax
#container-type: normal | size | inline-size;
container-name: none | <name>+;
container: <name> [ / <type> ]?;Values
#- The element isn’t a container for size queries. The rule
@container (width >= 260px)from the demo has nothing to refer to, so the card stays vertical even in a wide frame. This is the default value. - The frame exposes its width, and from 260px the card arranges itself horizontally. Drag the frame’s bottom-right corner to the left, and the card returns to a vertical layout.
- The container exposes both width and height, but its height stops being driven by its content. Without a set height, the frame collapses to just its padding, and the card disappears under
overflow: hidden. with a set height
With a fixed height, asizecontainer works correctly, and queries can also checkheight. Shrink the frame vertically by dragging its corner, and the image disappears.container: lesson / inline-size
shorthand: name / type
The shorthand sets a name and a type at once. The rule@container lessononly targets the container named lesson, and here it also changes the card’s background.
Values in practice
#normal
@container (width >= 260px) from the demo has nothing to refer to, so the card stays vertical even in a wide frame. This is the default value..demo { container-type: normal; }inline-size
.demo { container-type: inline-size; }size
overflow: hidden..demo { container-type: size; }size + height
size container works correctly, and queries can also check height. Shrink the frame vertically by dragging its corner, and the image disappears..demo { container-type: size; height: 150px; resize: both; }
@container (height < 110px) {
.thumb { display: none; }
}container: lesson / inline-size
@container lesson only targets the container named lesson, and here it also changes the card’s background..demo { container: lesson / inline-size; }
@container lesson (width >= 260px) {
.card { background: #1e1b4b; }
}Browser support
#Widely available · since 2023
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#- Make the container the wrapper around a component, for example a grid column or a layout slot, not the component itself.
@containerrules only style descendants of the container. - In the vast majority of cases, pick
inline-size. Thesizetype only makes sense when the container’s height is already fixed, for example in a panel with a set height. - Name containers after their role (
sidebar,main,card). With nested containers, a query then won’t hit the wrong ancestor.
Related entries
#Spotted a mistake or missing an example? Write to us.