Created:
Last modified:
Container Queries
This is the beginning of what will probably be a rough and ready first dive into using container queries. You have been warned
Ok started off a bit rocky. I didn't realise you couldn't target the container itself when the sizing
changed, just it's child elements. I had the @container-type: inline-size on the
individual cards below, and trying to change their backgrounds on size change. This is why I love to learn
by doing.
Another interesting thing to note is that by applying @container-type:
inline-size or @container-type: size the container apparently loses
it's ability to know it's own size based on it's contents. So when a container has been initialised, and is
nested inside a flex container sizing gets a bit funny. If that container-type
is set to inline-size this results in the container not knowing it's inline size
(width on rtl/rl, height on ltr/lr). However if it's set to size it the
container doesn't know it's own inline OR block size.
Testing: inline-size
The element wrapping these cards has display:
block and container-type: inline-size, and the cards also have container-type: inline-size set.
Testing: inline-size with flex container
Here we have the same set up as above, but the container wrapping the cards is set to display: flex. Because the inner most element has a size container type set, it
loses it's intrinsic sizing, which the wrapping container was relying on to size itself. As neither of
them now know their size the cards reduce to their smallest size which here is determined by the padding
value set on them.
Changing layouts
In this section I've added some hero images to the cards and change the layout depending on the container size.
Syntax
A container can be set by using the container-type property with size,
inline-size or normal set. A name can also be set for a specific container so that you can
target a particular one. A name is set by container-name, and multiple names can
be given to the same container via space separation. This really opens up some seriously interesting
possibilities.
There is as well a short hand to set both type and name in the one line with simply container. An example of this would be container: card /
inline-size which names the container 'card' and set it's type to 'inline-size'.
New units!
At first glance I was wildly overwhelmed with these new units I was suppose to learn, then I realised how simple they were.
cqw- Container Query Width - A percentage unit of the containers width
cqh- C ontainer Q uery Height - A percentage unit of the containers height
cqi- C ontainer Q uery I nline
- A percentage unit of the containers inline size (this can be different to width if the writing direction
and direction are set to
rtl / rl) cqb- C ontainer Q uery B lock
- A percentage unit of the containers block size (this can be different to height if the writing direction
and direction are set to
rtl / rl) cqmin- C ontainer Q uery Min-- the smallest value of either
cqiorcqb cqmax- C ontainer Q uery Max-- the largest value of either
cqiorcqb
But why
Since I heard about container queries, I've been somewhat wondering what all the hype is about. And even as I've been testing it out I've been a bit meh, what's the big deal. But I realise I coming from ~18 months of working on my own projects where I have control over all the CSS. In reality that's quite a privileged place. When you're building a component to be used in multiple places across multiple sites where you don't know how much space the component will have, this is where container queries shine.
Below I have copied the exact same code from above, but nested it inside a mock website layout, with an aside for a menu. If you compare the above cards with these cards at different media widths you can see at times their layout is different. This is because the cards below are smaller in width sooner than the ones above. If this were done in media queries alone all cards with the same code would be the same at different media sizes regardless of where in a code base they lived.
Menu
- Item one
- Item two
- Item three
- Item four
- Item five
Recreating an example
This CodePen by Max Böck shows a
beautiful example of using container queries to show differing information depending on the size of the
book's container. The book is a web component and the container-type is
inline-size, which is set on the :host of the component.
I love Miriam
Suzanne's CSS Day 2023 talk on container queries, and this lovely idea to remember, that she likes to
think of elements that you want to query via a container query having to carry their own containers on their
backs, like turtles. This is because you cannot query the element you are setting as the container. And a
web component is so great for this, because this shell element already exists, no need for yet another
useless wrapping div.
Oh and here's my entirely inadequate replication of Max's beautiful piece. It's just a tester for me, and I did whip it up in a day, so yeah it's not a polished piece by anymeans. But it's fun. You can drag (with a mouse) a book to a different section and see how the element transforms and shows more or less information depending on it's sizing.
This currently doesn't work on touch devices, but I'm hoping to add that a little later. Also I set the default to this Ste Johnson's books because those covers are SO cute!