A module can have plenty of room on one part of a page and too little room in a sidebar, even when the viewport is wide. A viewport-based @media rule cannot tell those placements apart. A container size query lets the module change layout according to the space available in a designated ancestor. section 10.0 section 10.1
A size query takes two steps:
- Establish an ancestor query container with container-type: inline-size. Optionally give it a name: container: layout / inline-size sets both properties. section 10.1.1
- Put conditional descendant styles inside @container layout (width >= 450px) { … }. The rule applies when the selected container is at least 450px wide; @container layout (min-width: 450px) is another supported form. section 10.1.1
A module in a narrow sidebar
Suppose a page becomes two columns at a viewport width of 800px, with its sidebar taking 30%. A media module that switches to a side-by-side layout at a 450px viewport width can then become cramped in that sidebar. Define the page’s main and aside elements as containers with container: layout / inline-size; replace the module’s 450px @media rule with @container layout (width >= 450px). The module stays stacked until its own available container width reaches the breakpoint, whether it sits in the main area or the sidebar. section 10.1 section 10.1.1
Listing 10.3 Adding container queries
@layer layout {
.l-page {
margin-inline: 1rem;
}
.l-page > * {
container: layout / inline-size; #1
}
@media (min-width: 800px) {
.l-page {
display: grid;
gap: 1rem;
grid-template-columns: 1fr 30%;
}
}
}
@layer modules {
.media {
padding: 1.5rem;
background-color: #eee;
border-radius: 5px;
}
.media__image {
margin-inline: auto;
}
@container layout (width >= 450px) { #2
.media {
display: flex;
gap: 1.5em;
}
.media__image {
align-self: start;
margin-inline: revert;
}
}
}
The complete stylesheet keeps the viewport query for the page’s columns but uses a container query for the module’s internal layout. section 10.1.1
Names determine which ancestor is measured. A named query uses the closest ancestor container with a matching name, skipping other containers. An unnamed query uses the first container it finds; an unnamed container must be established with container-type rather than the container shorthand. Naming containers makes a module’s intended reference point clearer. section 10.2.2
Use viewport queries when the page-wide layout should change, and size queries when a reusable module should respond to its local space. This pattern depends on defining containers consistently where modules may appear. Check browser support for users who may not have upgraded: container queries were supported in the latest major browsers as of early 2023. section 10.2.3 section 10.1.1
