With media queries you can adjust layouts based on the size of the viewport or the type of device being used. Container queries allow you to make more specific adjustments to elements based on the size and state of their ancestors, or containers.
Imagine you have a newsletter sign-up form that is meant to be used in several contexts on your site. You might want it to span the full width of the page on a signup page, but go into a split column on a page with other content.
As shown in this demo, with container queries you can adjust the properties such as font-size, padding, and the layout of the element based on attributes of its nearest container, independent of the viewport size.
Setting up a container query
Unlike media queries, container queries are established in two parts:
- Define a container.
- Write styles for a child element to be applied when a parent container matches the query's conditions.
Defining a container
You can define a container by using the container-type
property.
.my-container-element { container-type: inline-size; }
A container-type
of inline-size
lets you query the container's inline axis.
To query against both the inline
and block
axes, use container-type: size
.
main, .my-component { container-type: size; }
Both values of container-type
apply different types of size containment. Inline-size
containment on an element prevents its descendants from affecting its inline-size.
An element with size
containment prevents its descendants from affecting its size in both the block and inline axes.
In this example you can see size containment can affect the element on which it is applied.
Since it won't be sized based on the size of its children (the <p>
element), the container will collapse unless given an explicit size by setting its dimensions (that is, inline-size
, block-size
, aspect-ratio
) or placing it into an explicitly sized layout.
Container query conditions
Once a container is established, you can add a condition, wrapped in parentheses, that must be true for the styles inside of the container query to be applied. For container size queries, which are based on the dimensions of ancestor elements, the condition is made up of the following:
- a size feature:
width
,height
,inline-size
,block-size
,aspect-ratio
, ororientation
, - a comparison operator (that is,
>
,<
,=
,>=
), - and a length value.
.my-container-element { container-type: inline-size; } @container (inline-size > 30em) { .my-child-element { /* styles to apply when .my-container-element is wider than 30em */ } }
Size feature conditions can also be written with a colon and a single value to test.
@container (orientation: landscape) { /*...*/ } @container (min-width: 300px) { /*...*/ }
You can also combine multiple conditions by using keywords like and
and or
, or chaining multiple conditions together with operators.
@container (inline-size > 40em) and (orientation: landscape) { /*...*/ } @container (height > 25vh) or (orientation: portrait) { /*...*/ } @container ( 10em <= width <= 500px) { /*...*/ }
Naming containers
To target specific containers, even if they are not the nearest ancestor, you can name containers with the container-name
property. Then you can reference the container name you want to query before defining your conditions.
.sidebar { container-name: main-sidebar; container-type: inline-size; } @container main-sidebar (inline-size > 20em) { .button-group { display: flex; padding-inline: 1.25em; } }
The named container must still be an ancestor of the elements being styled.
Use shorthand with the container
property
The container
property lets you use a shorthand syntax to both define a container and specify the container type.
.sidebar { container: main-sidebar / inline-size; }
The name of the container comes before the slash and the type of container comes after.
Container query units
Within containers you also have access to container relative length units. This provides more flexibility for components that can exist in different containers, since the relative lengths will adjust depending on the dimensions of the container.
Here the container length unit cqi
(1% of a query container's inline size) is being used for the button's padding.
.container { container: button-container / inline-size; } .one { inline-size: 30vw; } .two { inline-size: 50vw; } button { padding: 2cqi 5cqi; }
Both buttons have the same relative units applied, but since the units are relative to the container's size, the second button has more padding due to its larger container.
Nesting container queries
You can nest container queries inside of selectors.
.my-element { display: grid; padding: 1em 2em; @container my-container (min-inline-size: 22em) { /* styles to apply when element's container is wider than 22em */ } } /* equivalent to */ .my-element { display: grid; padding: 1em 2em; } @container my-container (min-inline-size: 22em) { .my-element { /* styles to apply when element's is wider than 22em */ } }
Or nest them inside of other container queries or at-rules.
@container my-container (min-inline-size: 22em) { .my-element { /* styles to apply when element's is wider than 22em */ } }
@layer base { @container my-container (min-inline-size: 22em) { .my-element { /* styles to apply */ } } }
Check your understanding
Which size features can be used for container query conditions? (Mark all that apply)
width
block-size
inline-size
viewport-size
viewport-size
is not a valid size feature for container queries.height
With a container type of inline-size
, you can query a container's aspect-ratio
.
inline-size
cannot query the aspect-ratio
of an element since aspect-ratio
takes block-size
, or height
, into account.container-type
of size
to query a container's aspect-ratio since it takes into account the both inline and block dimensions of a container.If you wanted to use a container relative unit based on the height of a container, which of the following could you choose?
cqi
cqi
is based on the logical inline-size of a containercqq
cqw
is based on the width of a containercqb
cqb
is based on the logical block-size of a containercqvh
cqvh
is not a valid CSS sizing unitcqh
cqh
is based on the height of a container