@container - CSS At-rule
Summary of characteristics of the @container at-rule
Description of the @container at-rule.
The directive @container introduces the ability to write conditional styles based on an element's dimensions.
The right term is container query.
Note: a container queries request can only apply styles to the children of the element that was declared as the container. The container itself cannot be styled in a container queries request that concerns it.
In this first example, the Firefox logo is a floating image on the left, which allows the description to be next to the image.But if the container's width is too small, the lines of text next to the image will be very short, making reading difficult.
The container's width can be limited by the layout: for example, this container could be in a grid cell containing other elements, and the column widths are dynamic.
For the purposes of the demonstration, we made the container's width adjustable with the mouse.
In this second example, a container query was used to make the image non-floating when the container's width is too small (less than 200 pixels).As above, you can adjust the container's width with the mouse to simulate a layout constraint.
Syntax elements:
For any overflow, you need to define which element is the container and what type of container it is. This can be done with the properties container-name
and container-type, or more simply with the shorthand property container .
For the example above, we defined that the container's name is demo and that it works along the row axis. The image is also set to float to
the left by default.
#description1b {
container-name: demo;
container-type: inline-size;
}
#description1b img {
float:left;
margin-right:10px;
}
Note: the container ID can be set on a class, so not necessarily for a single element.
Next, you need to write the actual container query. This can only refer to child elements of the container. Here, we declare that the image is no longer floating if the container's width is less than 200 pixels.
@container demo (width < 200px) {
#description1b img {
float:none;
margin-right:200px;
}
}
Other examples.
We know that justified text doesn't look very good on short lines: it causes ridiculously big spaces between words. A container query was used to align the text to the left when the container's width is less than 300 pixels.
Here, the writing direction adjusts based on the shape of the container: if it's wider than it is tall, the writing is horizontal, and vertical if it's taller than it is wide.
Units specific to container queries.
Several units have been created to express dimensions based on the dimensions of the container element. See CSS units relating to the container.
Advantages of container queries.
The main advantage of container queries is that they allow you to style an element independently of the rest of the page. This is especially useful for components, which can be inserted into a page whose layout is unknown.
The requests like scroll-state. ⚠
These queries let you find out about the scrolling state of the container: can it still scroll in one direction or another? Is it a container with snapping
(scrolling with snaps)? And finally, for containers in sticky position, is the container stuck at one end of the screen, and if so, which one?
The style container queries requests. ⚠
This evolution of container queries allows testing any property of the container element. It's the computed value of the property that is taken into account.
But this feature is still not widely supported.
Syntaxes of the @container at-rule.
The very simple examples given here consist of a container element that serves for containment, and an internal element on which the properties are adjusted. It is indeed not possible to change the properties of the container itself.
- @container id (width > 200px) and (width < 400px) { ... }
This is the basic syntax of a container query.
idis an optional identifier. It will have been set by the propertycontainer-nameorcontaineron one or more elements of the page.
If it is not provided, the query applies to all containers on the page.(width > 200px)is a condition involving a property and a value. It's the computed value of the property that is considered.and,orornotare operators that allow you to combine multiple conditions, with each condition being written inside parentheses.
The properties that can be used in conditions are:
widthandheight: width or height of the container element.inline-sizeandblock-size:size of the container element in the inline direction, or in the block direction.aspect-ratio: ratio corresponding to the width of the container element divided by its height.orientation: takes the valuelandscapeif the width of the container element is greater than its height, and the valueportraitotherwise.
Tests on height (
height), block direction size (block-size), ratio, and orientation are only supported on containers of typesize(seecontainer-type).
This text turns red as soon as the width is less than 150 pixels.This text turns red as soon as its orientation is in portrait. We wrotenot(orientation:landscape), which comes to the same thing. Change its dimensions to see for yourself.This text turns red as soon as its width is less than its height. Change its dimensions to see it happen.
Browsers basically recognize another syntax, inherited from the past, which is less readable than the previous one. Here is this old syntax, along with the equivalents.@container id ((min-width: 200px) and (max-width: 400px)) { sélecteur { propriétés CSS } }min-width: value⇔width > valuemax-width: value⇔width < valuemin-height: value⇔height > valuemax-height: value⇔height < value - @container id scroll-state(stuck:top) { ... }
The
stuckdescriptor is only active on elements whosepositionproperty issticky. Used with thescroll-state()function, it activates when the container element is "stuck" by one of its edges:none: thestuckelement doesn't play any role.top: the element is stuck to the top edge.right: the element is stuck to the right edge.bottom: the element is stuck to the bottom edge.left: the element is stuck to the left edge.block-start: the element is stuck to the edge corresponding to the start of the blocks.block-end: the element is stuck to the edge corresponding to the end of the blocks.inline-start: the element is stuck to the edge corresponding to the start of the lines.inline-end: the element is stuck to the edge corresponding to the end of the lines.
The type of container (
container-type) must bescroll-state.The example below is made up of a container block (id=stuck-container), which contains a text element (id=stuck-element). The container block is
position:sticky, it receives the propertiescontainer-type, set toscroll-state, and an ID defined bycontainer-name. The element turns red whensticky:bottom.
Scroll the page up to stick the block to the bottom of the screen.⚠ This doesn't work on all browsers.
This text turns red as soon as it's pasted by its lower edge. - @container id scroll-state(scrollable: top) { ... }
The
scrollabledescriptor is triggered when the container can be scrolled (presence of a scrollbar and content exceeding the container's size).none: thescrollableelement doesn't play any role.top: the element can be scrolled up.right: the element can be scrolled to the right.bottom: the element can be scrolled to the bottom.left: the element can be scrolled to the left.x: the element can be scrolled horizontally.y: the element can be scrolled vertically.block-start: the element is stuck to the edge corresponding to the start of the blocks.block-end: the element is stuck to the edge corresponding to the end of the blocks.inline-start: the element is stuck to the edge corresponding to the start of the lines.inline-end: the element is stuck to the edge corresponding to the end of the lines.block: the element can be scrolled in the direction of the blocks.inline: the element can be scrolled in the direction of the lines.
Here too, the type of container must be
scroll-state.The main element is the containment container (id=scroll-container). It contains an element (id=scroll-element) with text long enough to require scrolling. Two container query requests display the element in blue when scrolling up is no longer possible, and in red when scrolling down is no longer possible. Keep in mind that these queries can only affect a descendant of the containment container.
⚠ This doesn't work on all browsers.
This text turns blue when it can no longer be scrolled up, and red as soon as it can no longer be scrolled down. This required two container query requests.
- @container id scroll-state(snapped: block) { ... }
The
snappeddescriptor lets you check if the containment container is anchored. So it needs to be in a container with scroll anchoring.none: thesnappedelement doesn't play any role.x: the container is an element with snapping along X.y: the container is an element with snapping along Y.block: the container is an element with snapping along the block axis.inline: the container is an element with snapping along the lines axis.both: The container is an element with snapping along both axes.
Here the containment container is multiple. It has the ability to anchor during scrolling (
scroll-snap-align:center). It of course receives the propertiescontainer-nameandcontainer-typewhich make it a containment container, along with some other formatting properties.
Above it is the scrolling container with anchoring (id=container) with the propertyscroll-snap-type:y mandatory.
If needed, refer to the tutorial on scrolling with snaps.By using the scroll bar, you anchor each of the elements one by one. The one that's anchored gets a colored background.
⚠ This doesn't work on all browsers.
1
2
3
4
- @container id style(propriété:valeur) { ⚠ ... }
The
style()function lets you check for a property that would be applied to the container, either directly or through inheritance. For now (2026), it only works with custom properties.⚠ This doesn't work on all browsers.
This text turns red as soon as its alignment is centered.This second paragraph isn't centered.
Browsers compatibility with the @container at-rule.
The @container at-rule is well recognized when it comes to tests on container dimensions, but not yet for scrolling tests with
scroll-state() or style tests with styles().
@container at-rule which greatly facilitates the writing of components.scroll-state() function with the @container at-rule.style() function in the syntax of the @container at-rule.@containerat-rule
scroll-state()in
@containerstyle()in
@containerBrowsers on computers :
Mobile browsers :
Outdated or marginal browsers :

Internet Explorer

UC Browser pour Androïd

Opéra Mobile

QQ Browser

Baidu Browser

Samsung Internet

Chrome

Edge

Chrome pour Androïd

Androïd Brower

Firefox pour Androïd

Opéra

Safari

Safari sur IOS

Firefox

KaiOS Browser

Opéra mini
Evolution of the @container at-rule.
-
CSS Containment Module Level 3
Level 3 of this specification specifically defines container-relative units of measurement, in order to make each element on the page independent.
Regarding@containerIntroduction of "containment" techniques and the@containerat-rule.December 21, 2021Working Draft.
See also, regarding containment techniques.
The properties and other concepts related to confinement are described in the specification CSS Containment Module.
Properties:








