CSS container queries are similar to media queries, but related to a container element size rather than the viewport size. While adaptive layouts often set breakpoints based on the viewport using media queries, we can use container queries to achieve a similar effect when creating modular components in a design system.
But can we use Container Queries?
At the time of writing, in January 2022, container queries are only available after opt-in by feature flag, so don't expect container query support in your regular end-user's browsers today. But, like Andy Bell wrote, we can start to use container queries progressively right now:
If the browser doesn’t understand some CSS, it’ll ignore it and carry on parsing the rest, so we can effectively use container queries today.
What not to use Container Queries for
HTML websites are responsive out of the box. Without adding style rules, text content will adapt to fill the browser window so that it does not flow out of the visible area. Adding a few lines of CSS, we can make images behave the same (provided we set their width
and height
or an explicit aspect-ratio
).
img {
max-width: 100%;
height: auto;
}
Provided that we properly stated the actual (intrinsic) image sizes, we can apply this rule safely without any media query or container query. If the image is smaller than the viewport width, the rule will have no effect. On smaller screens, the browser can use the resulting aspect ratio to calculate the height and resize the image without distortion. And if we want to hide an images on mobile screens, we can use a picture
elements with a srcset
to prevent loading hidden images.
Use Cases for Container Queries
Maybe we want to toggle the flex-wrap
or flex-direction
property, set position: fixed
with a z-index
, or change typography and colors based on the available space for our component, depending on how much space is available for our component.
By taking into account a parent container rather than the whole site, we can design web components that can be reused inside other columns, dynamically changing their appearance based on the width or height that is actually available.
The "Flexbox Holy Albatross"
At beyond Tellerrand conference 2019, Heydon Pickering presented the "Holy Albatross" a layout using sophisticated CSS that will become more elegant and readable by using container queries.
The idea of emulating container queries using other CSS properties had become an ambition obsession like searching for the Holy Grail, impossible to avoid like the Albatross vendor in a sketch by Monty Python's Flying Circus, so he called his code the Flexbox Holy Albatross.
Emulating Container Queries in a Flexbox
In Heydon's example, a flexbox will automatically switch from horizontal (multi-column) to vertical (single column) flexbox layouts, by a calculating a flex-basis based on the difference between our breakpoint (640px
in the below example) and the available container width (100%
).
This technique works pretty well, but the code is not easy to understand.
.container {
display: flex;
flex-wrap: wrap;
--margin: 1rem;
--modifier: calc(640px - 100%);
margin: calc(var(--margin) * -1);
}
.container > * {
flex-grow: 1;
flex-basis: calc(var(--modifier) * 999);
height: 20vh;
margin: var(--margin);
}
Let's refactor the code using container queries.
Using Container Queries
First, we have to make sure we can actually use them, which is currently an opt-in preview feature in Chrome and Chromium-based browsers like Edge or Vivaldi.
Navigate to chrome://flags, search for container
, switch "Enable CSS Container Queries" to "Enabled" and restart your browser.
Refactoring the Albatross Flexbox Example
We don't have to use the contain property anymore (since 2022 use container-type
instead!) to explicitly define our container as a container element (similar to using position: relative
to define a parent context for position: absolute
).
@suprabhasupi's article Future of CSS - Container Query explaines containment and container queries, providing a hands-on example.
To define a container that enables container queries based on width and height, we used the existing containment property contain: size
, but since 2022, container-type: size | inline-size | block-size
has become the preferred syntax.
In many common use cases, we are only interested in the width. This is what the new container-type: inline-size
is for. This common use-case also applies to our flexbox example.
Edit (August 2022): I have updated the code example below to reflect the recommended syntax, which is more intuitive anyway. For more information and other possible container-type
values, see CSS Container Query Syntax Update.
.container {
container-type: inline-size; /* obsoletes old experimental contain: property */
/* deprecated: contain: layout inline-size style; */
}
@container (max-width: 640px) {
.container > * {
flex-basis: 100%;
}
}
If you see a pink border around the albatross boxes in the small-container vertical column layout, your browser has applied the styles based on CSS container queries.
Shipping Stable Code to Production
At the time of writing, no popular browser supports container queries by default. So what's the point in using future CSS right now?
Code Usage as Vote for a Feature
Code is crawled and examined by various parties like Web Almanac, search engines and browser vendors. This was how semantic HTML 5 elements like nav got their names and this might also be a hint for decisions on what features to prioritize and which ones to deprecate.
Citation needed: I overheard that there is still similar research going on to help decide which browser features to prioritize, but I did not find any official statement to acknowledge this claim.
Adding Fallback Code
We can add a container query emulation like Heydon's "Flexbox Holy Albatross" or use a container query polyfill as a polyfill and switch browsers or feature flags to make sure that our code works as expected with or without container queries.
Top comments (3)
Thanks to Una for suggesting to update my code example!
This is only one property change that makes the code much more human-readable:
For more details and other possible
container-type
values, see:CSS Container Query Syntax Update 2022: container-type
Ingo Steinke ・ Aug 30 ・ 3 min read
Great post. I am wondering to find use cases of container-type: size; . since after we apply as size the element looses the height. I could not find any example on the purpose of using size.
Great article! For everyone who likes to see more code snippets and examples, here’s a good read about Container Queries (in German)