One of the coolest responsive features in CSS,
which we don’t talk about nearly enough,
is the way we calculate layout
based on both context and content.
Add more content,
and a container will try to grow,
but it might also be constrained by context,
or explicitsizing.
That’s very cool,
but if you add container queries,
it becomes an infinite loop:
as the container gets larger, we make the content smaller,
which makes the container smaller,
which makes the contentlarger.
2010-2020
🚧 Laying Foundations 🚧
So for a long time,
this seemed impossible to implement.
But behind the scenes,
a lot of people
have been laying the groundwork inbrowsers.
Last year two proposals emerged,
showing different ways we might pull this off.
Both are interesting,
but David Baron’s approach has the most momentum right now,
and I’ve been working on it
to flesh out some of the details,
and start writing aspecification.
The first thing we need to do
is define our containers–
Anything we want to be able tomeasure.
No Content Sizing
In order to avoid any layout loops,
we need to turn off content-based sizing.
Our containers need to be sized
without reference to anything insideit.
.container{ contain: size layout style; }
We already have a property for this!
It’s called contain,
and allows us to “contain” various types ofthings.
Size containment turns off content-based sizing,
layout containment is kinda like a clearfix –
wrapping around floats and margins –
and style containment keeps list-counters
from leakingout.
And we’re going to need all three of these
for our container querieswork.
2D size containment
Is Too Restrictive
But size-containment is…
bad in most cases.
It’s just not possible to build all our containers
with explicit widths and heights!
We usually need one axis to be fluid,
so that extra content has somewhere togo.
We needInline Size Containment
Most layouts work by containing the width,
or the inline-dimension,
and allowing the height to grow or shrink
with the content.
So we’re adding an option to make
single-axis containmentpossible.
.container{ contain: inline-size; }
Contain inline-size.
We’re not sure if we can also allow
a block-size values here.
That needs some moreexperimenting.
In our initial proposal,
applying the appropriate containment –
layout and 1d or 2d size –
creates acontainer.
That’s how the Chrome prototype currently works,
but you can see it’s a lot to remember,
and it’s not obvious what’s goingon.
.sidebar, main, .grid-item{ container: inline; }
So we’re working on a simpler syntaxhere.
Instead of specifying all the containment required,
we just say what type of container we want –
or what we want to query.
In this case we want to query the inline size.
Browsers can take that,
and apply the right containment
in thebackground.
This syntax is still very much in development,
so it could change a lot.
There’s some concern around having
a container property
that is so similar to the contain property.
A container-query
looks exactly like a media-query,
but with at-container instead of at-media.
And each element will query
the size of it’s nearest ancestorcontainer.
That’s another important limitation
to make sure there are no loops.
Container’s can’t querythemselves.
<divclass="container"> <divclass="container"> <divclass="container"> We can nest containers! </div> </div> </div>
But why don’t I just show you?
I’ve set up two containers on the page,
each with one card using a media-query,
and one card using a container query.
The media queries all trigger at the same time,
but the container queries
depend on the size of thecontainer.
In some cases,
like inside flexbox or grid,
there is no outside container
that will tell us the actual space available
for each item.
But we can get around that by adding a container
around each component –
in this case div.card is wrapping each article.
The outer div establishes a container,
and the inner article can queryit.
Max Böck has created this bookstore demo
with self-contained web components.
Each component host element is a container,
and everything inside the component
adjusts based on availablesize.
Of course, we can also get creative!
Jhey Tompkins made these interactive blinds
that get smaller as the container gets bigger.
Because CSS doesn’t have to be practical
to beawesome.
Migration path
Using @supports
@container(width > 30em){/* CQ support */}
/* actual syntax TBD */ @supports not (container: inline){ @media(width > 40em){/* no CQ support */} }
I’m recording this in advance,
so check back.
I’ll share the link to my slides,
and update this one with more resources
before the conferencestarts.
Building on
Existing CSS
Building on the existing features of CSS–
Already make…
Styles Responsive
But particularly the overlap
between the two main goals of CSS:
to make responsive–
Already make…
Styles Reusable
and reusable styles.
Building components that are inherently responsive–
Modular CSSResponsive Components
There’s already been a lot of progress in this space, with tools like grid & flexbox & aspect-ratios – but Container Queries help us get a littlecloser.