Introduction to Container Queries
00:00:00
Speaker
Container queries are one of those new CSS features that everybody's super hyped about and with good reason. It finally gives us a way to style, scope, and build responsive components against the actual width of the parent rather than the width of the whole viewport. And while this is incredibly powerful and incredibly cool, it's a bit complicated. There is a lot of new stuff you have to learn.
00:00:20
Speaker
There is the actual CSS query that is new that allows you to trigger and to find what rules happen when that trigger happens. That's the actual container query itself. There's new properties, container type, container name, and container. Why are there two? Why are they different? Which one do you use? And even maybe the most confusing part of them all is that there is not one, not two, but there are six new CSS units related to container queries.
00:00:48
Speaker
What are the differences all, and when do we use
Understanding Container Queries
00:00:50
Speaker
them? Well, we are covering all of that today, here in the Batted CSS Podcast.
00:00:59
Speaker
Adam, I have been studying container queries lately because I said we're going to do an episode on it. And one of the things I finally realized with container queries is I understand them. I for a while, I'm still bad. I'm still bad. I'm still bad. Oh, I was like, dude, you can't start an episode saying you're good at something. No, no, no. I just said I understand it. Uh, yes. Yeah. Not the same. And I understood it before, but I,
00:01:27
Speaker
I was always bogged down by the syntax or by, I think I, I did that thing where I started understanding something too soon, or at least, you know, too soon for people not like you who are like, it's their job to understand it too soon. But the spec changing so much made me be like, wait, what is happening now that the, you know, this is a thing, this is a, you know, a thing people can use. I get it. But I get why.
00:01:52
Speaker
It's one of those things that people are like, yes, I know what a container query is maybe, uh, because there is, there's a whole lots of container queries. The more than just saying that it's a new way of building responsive, you know, CSS. So that's what we're going to cover today. I know enough, but you know more. So I want to start out in your own words, Adam.
Component Context vs Viewport
00:02:15
Speaker
What is a container query?
00:02:19
Speaker
without saying that it is containers or container. Uh, so yeah, it's this, so it's where things are. So back in the day, we'd make pages and that's where it was, but we're kind of at this point now where screens get really, really big. And they also get really, really small, even down to like a watch.
00:02:42
Speaker
And the viewport is less relevant in these moments when you have components that you're trying to move around to different places based on their most useful context that they have. So it's like, we don't care about the size of the entirety of the page or the document anymore. We care about this component owning its own responsibilities in the moment where it's used. And a container query allows you to, by default, query the nearest container
00:03:08
Speaker
which is probably pretty common. You know, like if you're in a card, the classic card, you're going to find the card size and query off of that. But you can query multiple things. It's not limited to just the nearest parent. You can reference something by name, which is really nice. So you can have layers
00:03:26
Speaker
of these containers and adapt yourself to each one accordingly based on a use case. And it's just really nice. It's sort of, it just really follows along this. Like we want our components to be portable. Have we just talked on the show about how you asked a gorilla for a banana, but you got a gorilla holding a banana? No.
00:03:43
Speaker
Oh, it's one of my favorite code things. We always talk about code, like it's all abstract and it's, you know, Oh yeah, it's easy components and classes, you know, it's no big deal. There's no strings attached. And so you're like, Oh cool. I'll just take this component off the shelf and it's a banana. And then you grab the banana, but Oh snap. As you're pulling banana towards you, you're like, Hey, the gorilla is still attached to this. And it's like all these other things that you have to do to actually get the class or the components work. Yes.
00:04:07
Speaker
So anyway, as we seek towards making actually portable bananas, container queries help us container bananas.
00:04:16
Speaker
I did not have that on my bingo card, but I'm glad it was said. So there are multiple properties that come in with container queries for first, you have to define before you can contain anything or just spot, just do the triggering of
Defining Container Properties
00:04:32
Speaker
the actual query itself. You have to define what the container is and you know, optionally, but preferably give it a name, which axis, which axis are you trying to, to query? Yeah. So out of what, what are those properties?
00:04:46
Speaker
Well, you can choose inline, which is pretty much the only one that works, which is like the width, but you can contain size, which is height and width, or you could contain block. And I'm excited to tell you towards the end of this episode, I had a recent use case to use contain container size and to query both height and width, which really, there's a very niche use case for it. But anyway, that's the primary, I think, right?
00:05:12
Speaker
Well, if you specify container, you, so basically the way it works is you have to say, all right, we have a container, uh, element, and this is what we're going to pay attention to and be able to apply rules to, which is another thing I think that makes, uh, container queries a bit difficult is that.
00:05:29
Speaker
there's really three aspects to containing it, whereas with a media query, there's two. So with media queries, I create my rule, and then I create the media query, and then I change that rule inside of there. And it's like, I make it. I change it. With container queries, I need to define the container. I need to make the rule. And then I have to change the rule. And there is more.
00:05:59
Speaker
Like more places to get lost and to have to like connect together. Now there's easier ways of container queries to solve that. But what I've found is, is that you end up kind of writing more upfront to have more power in the long run. It was like, there's an ahead of time aspect. Yeah. You have to know what, what you want to query, which also means you have to know who you want to query. And you also have to know that the item can't query itself.
00:06:23
Speaker
which is tricky too like in a card people would want to put contain like a container and they'd say inline size and give it a name and then the card is like well I want to switch to landscape when I don't have enough space well it's like you can't query yourself so yeah there's like a lot of a lot of little things have to
00:06:40
Speaker
line up, um, to actually get the container query to work. Yeah, you're right. Yeah. And so you, you specify a container, you give it a name and then from there you want to say, well, what are we querying on or like, what are we, uh, what are we.
00:06:56
Speaker
What are we paying attention to? Are we paying attention to the height? Are we paying attention to the width or are you paying attention to both? And then what I think also is difficult too with container queries is that as CSS developers, we grew up being like, we pay attention to height and width. And then logical properties came onto the scene and we're like, actually, you don't pay attention to height and width. You pay attention to block.
00:07:20
Speaker
and inline. And block and inline have always existed, the whole concepts of block and inline. But we didn't really think about them that much in terms of writing modes now. And so container queries very much rely on that by saying, hey, yes, you can talk about width, but you're really talking about inline. And yes, you can talk about height, but you're really talking about block.
00:07:46
Speaker
And I think that is one of those things that if you're not familiar with logical properties and writing modes, container queries is going to be very confusing for you at first because it's kind of like, Oh, you don't know about those. Go watch this other video or go to chapter seven and then come back and then continue on learning, which is another, uh, and I've been, you know, because, uh, because you're my friend and because you have shown me the light, I use logical properties, uh, in production to, uh, yes.
00:08:16
Speaker
And so I understood that. But I also understood that, wow, that's something that could be really difficult
CSS Shorthand vs Longhand
00:08:24
Speaker
It is super difficult at first. Cause yeah, it's an entirely different way of thinking about it. You have to think less about yourself and more in sort of a global way. But yeah, I always like to think about it. You learn one thing, you get to reach everyone. Whereas right now we're learning height and width and you have to rotate your mind for ways to reach the international audiences and logical properties. You don't, you just have to learn one. So with container queries, we define a container. We optionally give it a name. Name is optional. Yeah. Name is optional, but preferred.
00:08:54
Speaker
I think so. Yeah, it shows some intent, you know? Well, I'm going to get into a little section state for this, why I think named containers are really like the way to go most of the time. But one thing that I'm confused on is that.
00:09:10
Speaker
What are, what are the properties for defining a container? We have, we have container, but I thought shorthand, which is shorthand. You can put multiple ones in there. And then I thought there was the long hand, whereas you can write container style where you can write container. Let's, let's do some quick, uh, searching of that. I'm sure it's container type. Let's figure this out. Yes. It is container type.
00:09:39
Speaker
Then I got this wrong. Oh, look, you can't specify block size. So yeah, it is just container type. So container allows you to say the name and then a slash and then the type, uh, or you can break them out into longhand and container dash name and container dash type. Yeah. I was just confusing the two. Yeah. So you were saying you have two properties. You have container type and container. That's it. And so container type where you can say container name is the other one container name. That's so you have three properties, technically three. Yeah. One is shorthand for the other two. Yeah.
00:10:08
Speaker
That's right. But that's, you know, that's typical CSS, uh, where I think a lot of learning CSS is just figuring out which properties are related to other properties and not being confused by that by, by saying like, Hey, you know, it's like when you look at a button reset, you can be like, but it's a button and you're like, why?
00:10:28
Speaker
Why are there 20 properties? And you're like, no, it's okay. These are all related to each other. It's, it's fine. Same thing with any setting anything with the background. You're like, whoa, that's a lot of stuff, but they're all related. And in some ways, not all the time, but sometimes you can put all of those things on one line, but maybe that's not preferred because that can be even more confusing than, you know, it's like doing a math problem, not showing your work.
00:10:52
Speaker
Very much so. Yeah. You take the mystery out of it when you use the long hands. I mean, I could see a style in things saying you can't use any short hands. I can also see the CSS working group saying the short hands were a mistake. Like look at padding and margin right now. You can't do a logical versions because the shorthand is physically baked. That's just fun to say.
00:11:13
Speaker
Yeah. Uh, so yeah, we have container. So we specify a container and with either container, the full powerful, the shorthand one. Uh, and then we have individual ones for container type container name and container. Uh, we can do that container name and that's it. And that's it. That's right. The third one is the shorthand. Yeah.
00:11:36
Speaker
So from there we can say, we can define what we're doing. Like, Hey, I got this card. Cause of course we're always going to go with cards. And now I want to move on to querying it, the actual container query itself. And I think this is the syntax that you see everyone like, Oh, we got, like we got an at container. That seems cool. And at first I was not, uh, I did not fully understand really.
00:12:02
Speaker
the power behind at container because I was like, okay, at container allows me to say, Hey, whenever the container is within a certain width, or I can even use logical properties inside of the range, whenever the inline size is something like that, do these things.
00:12:17
Speaker
And to me, I'm like, this seems like a little bit more of a specific media query, because with media queries, the problem is media queries are junk drawers. Like, let's just be serious. Media queries are like, you can try to be really clean about it. You can try to figure out where you want to scope them in your components and all that.
00:12:36
Speaker
But at the end of the day, you will store a lot of unrelated things or complicated things all in a media query. And if you give up any discipline on it, it's just you pull it open and you're like, ah, that's where I put the clamp function for the read. Actually, I don't know why you'd have a clamp function in there, but that's where I put that thing. So like media queries are junk drawers.
00:12:58
Speaker
Container queries, I was hoping would be a way to not have junk drawers. And when I saw a container, I'm like, well, that's just like a more organized drunk drawer. I was like, because I can spoke scope it down to the parent size, but it's still a bit of a junk drawer because I can't scope it down to the element. But with names now you can do I have that right.
00:13:20
Speaker
Yeah, you can query a specific name. And so it's not going to, again, you take the mystery out. So just like how you're saying with short hands, you can set all these properties with a shorthand, but somebody has to know how to unpack that same thing with a container. If you don't specify the name, someone has to guess where the nearest one is and it could be different anywhere you place the component. But if you give it a name, you're being very deliberate with what you're doing and you're leaving some breadcrumbs behind. So you gave the thing a name and then some child queered the thing by name and you're like, Oh, I see what's going on here.
00:13:52
Speaker
Yeah, with naming, it seems to me almost mandatory. Like I'm sure there are cases where it's not, where it's good to have an unnamed for some catch all type thing. But if you don't name something, it seems like you're just falling back into the junk drawer category of, uh, of media queries where it's like, I'm just, just putting everything in there. You know, it's sure it's in there, but when I give it a name, you're, you're,
00:14:19
Speaker
you're scoping it, you're providing intention. And if you put all this in something that I'm a big fan of single file components, and if you put it all this in a single file component, now you're cooking with gas. Like it looks great. You're giving your component has a name, your container has a name, and you're writing this thing that's scoped all within there. And you can almost look at that file as like this contains
00:14:44
Speaker
all of this, this is hermetically sealed and I can go port this to somewhere else. And I know that it's going to be fine because it doesn't matter what the view ports doing. It matters what that component is doing and what forces are influencing it. I could definitely see a counter argument though, where like, um, as soon as you give it a name, you take away its portability and you create a, you create a tight relationship, not a loose one, a tight relationship between
00:15:11
Speaker
that child needing to be in a container of that name or else the queries don't work at all. So I could see if you want truly portable, um, making a component that is anonymously querying at container just says, Hey, the nearest container that can tell me the inline size of where I am, I'd like to adapt to that.
00:15:29
Speaker
And that way your component can move more places with knowing less about the destination. Um, but this is, this is a classic conversation. This is just like TypeScript versus JavaScript, right? We're looking at it like, do you want L and R on your socks or not? You know? Oh man. I do. I do like L and R on my socks. This is really good.
00:15:52
Speaker
I'm like, my socks are over engineered. They're telling me which foot they go on. I'm like, come on. Now I have Lucy's. I got a Lucy over here with an L on it. I could have put it with another. Anyway, it bothers me so much too. And they get like, uh, you know, you get the socks out of the wash and then there's like, I got two L's of this because you get some of the same sock and then they get, you unbundle it and then you see the two L's and you're like, I,
00:16:15
Speaker
This is, this isn't two else. This is one big L. You know, I just, I just took an L because I've got an L on my R. This is ridiculous. This is going to be a bad day. I assume that you also don't put your utensils in specific drawers. You just got like a big drawer. Okay. All right. All right. So separated from the big ones. Yeah. Okay. So you, there's, you have some decorum. All right. Just not, just not on your feet.
00:16:42
Speaker
Yeah, it's just, it depends on where it is. Yeah. I feel like socks. It was like a little over engineered. I was like, this was cute. I tried it and it, uh, there's just a new, it's a trade off. I'm like, and I don't like the trade off. I preferred when I could just put socks on willy nilly anonymous socks versus named socks. How did container queries get
Logical Sizing and Media Queries
00:17:01
Speaker
turned into socks? That's actually, actually it kind of fits. It does.
00:17:06
Speaker
And so I see this now because this is similar to at scope. We're at scope basically says, what's the nearest parent? And I'm going to scope that. And with that scope though, to my knowledge, takes a selector does take us always because you go within this. It can be anonymous, but it's a, it would scope its containment and doesn't reference anything in its parent.
00:17:30
Speaker
Well, if you put it in like a style tag, it will go to the nearest and you will go to the nearest proximity to the elements. Yeah, that'll find the proximity to nearest elements that it's by. So it's physical style tag near the button tag. You put it next to changes.
00:17:46
Speaker
Which you can mimic the same. I guess you need a rule, but it's like not too dissimilar where we're basically saying like it's close enough. It's finding it's matching it. You're, you're, you're doing some sort of proximity to say, this container is associated with, you know, this container query is associated with this container. Because if you don't provide a name, this is probably something I don't think we've covered well enough. And maybe something I am also very bad at. If I do not provide a name to a container query, Adam, how does it find what container it belongs to?
00:18:15
Speaker
recursive parent node crawling to the first one with a container type defined. Damn. That was like, I feel like we should let everyone know we did not practice that. That was so, you just nailed the crap out of that. Like I was like, here you go. Like, you know, like throwing the ball and then you were just like ready to go.
00:18:41
Speaker
And I slam dunk it in your face. Now I'm wiggling my tongue at you. Yes. Oh, my God. Oh, my gosh. All right. So what is that? What is recursive node parrot crawling dunking again? Well, it's going to so like it can't query itself. So the container like let's say you put it on.
00:19:06
Speaker
a button, and it wants to know if it should be a full width button or like a shrunk down button or whatever. Anyway, so you'd say add container, and that button's like, okay, I can't query myself, so my nearest parent in the DOM. And this would be contextual too, right? So if you got the same button in multiple areas, it's gonna find the nearest one. So it's gonna look at its parent node. So I said parent node, because like I'm talking about like JavaScript, you have a reference to your element, you do .parent node, and it'll give you a reference to the parent.
00:19:34
Speaker
So it looks at that parent and says, hey, do you have a container type? No. Okay. Next parent. Do you have a container type? No. And then it's like next parent. And so that's what I mean by recursively crawling parent nodes until it finds one with container type. And it would be like, Oh, you have container type. Is it inline size? No. Ah, that I don't care about you because this container query was against width or inline. And so yeah, it'll do that until it finds a container that matches and it might even end up being the body or the HTML tag.
00:20:00
Speaker
those will resolve. So a container query will resolve to the viewport if it found none, which also means you could entirely go in on container queries and never write a media query again if you don't want to, except for things that are actually media specific. But yeah, in terms of width or you could switch.
00:20:20
Speaker
Oh, I never considered that. So that basically if you have a container query of inline size on a full width body, it's basically a media query. It's like that, you know, the office meme with, you know, with Pam where it's like, it's the same picture. Like.
00:20:41
Speaker
the media query of a full on a body where if that's the only media query you write or container query you write for the body, it's the same thing as what a viewport media query would be. There is one clutch difference and you'll find this on my website nerdy.dev. If you read a blog post and you switch to a Japanese vertical writing mode. So if you visit from Japan and you prefer reading that way, my site will go vertical right to left. Now it's clutch. It's not even optional.
00:21:10
Speaker
to use container queries for that use case because media queries are about the media, the physical aspects of the device. A media query has no concept of logical directionality. And so on my site, I use a container query to see if the inline size is, and that's how I'm able to make sure my site can go
00:21:30
Speaker
in any direction because I'm not querying the devices with, I'm querying the pages in line size. So they are almost the same except that container queries have that logical aspect that kind of makes them better.
00:21:46
Speaker
Yeah. Wow. So you basically could say, I'm not writing a media query ever again. And if I want to be really lazy, I am going to write a body. My container is the body or the HTML tag. And we're just going to use it's a container for that tag. There's no other container queries in the whole website. And we're just basing everything off that, which is effectively media queries, but with the logical sizing or logical properties. Yep. You could do logical mobile first.
00:22:17
Speaker
That is so intriguing. Wow. I had another point and that just has like blown my mind thinking about it that way. Oh yes, with container queries. So if we don't give it a name, your argument has like, Hey,
00:22:32
Speaker
I now have this portable bit of a non named container query. So this is at container. Uh, and now I can add that in like imagine a world with CSS modules native or classic CSS modules.
Portability of Container Queries
00:22:47
Speaker
I can import that and say, Hey, it goes into here and it's just going to go to the nearest type of parent.
00:22:54
Speaker
But if I name it, now it's like, oh, why did you have to do that? Now I'm going to go and augment it or name it again. Name it again. It's just like typescript. You're like, oh, you typed and made it very firm. Now I have to go teach it everything new. Yeah. We did this episode, Adam. We don't have to do it again. There's just so much hand holding sometimes. I'm like, everyone makes it sound like it's easier. I'm like, no, you're really holding its hand more. I don't know. The amount of control, it's just a balance. Control is a balance. Yeah.
00:23:20
Speaker
that is super fascinating. One of the things though that it makes me, oh, you're probably going to hate this analogy even more is that it feels more even like, uh, I can't believe I'm saying these words. Everyone's going to turn off the podcast. Uh, it's kind of like Java where it's like, well, well,
00:23:38
Speaker
It's a container query factory resolver class where it instantiates a container query that has a name. So what about, there's a, we conceptually say, I don't even know if this is, tell me if this is possible in a world where I have these
00:23:58
Speaker
abstract container queries. They understand who they are. They understand what they do. And then if I want to apply it and name it, is there a way for me other than augmenting the whole sheet to say like, I could see this working with a theoretical mixin pattern where it's like, Hey, uh, this sets up a container query, but it gives it a name where it's almost like a function where I'm returning a quick container query from a function, but giving it a name.
00:24:23
Speaker
Wait, what was the question? I'm just following. You're like, yes. And, uh, but can I do that is basically like, what, is there a pattern for me basically to say, Hey, I have a generic container query that can apply to all different sorts of cards.
00:24:41
Speaker
And, but that card is name is profile card. And I need to give it the name of profile card. Cause I don't want to go through and refactor it. Or I just, I want names because that gives, I like the intention. I like my hand being held. How are there ways to take generic container queries unnamed and kind of knew them into names.
00:25:03
Speaker
like give them a name on a flight. Yeah, so it's like a base class, a container query base class that then you can extend with a name optionally. So at first I was thinking what you wanted was at custom media, which is a way to stash a media query into a name. And that's where I do like dash dash motion okay is equal to, you know, prefers reduced motion, no preference.
00:25:22
Speaker
But, um, I think you're right and that you would need some sort of function or mix in that would take parameters that could then fill in and then insert that into the page. No, nothing like that exists. I mean, you could write a JavaScript function to do it, but yeah. You could do like a, I wonder if we could do like a post CSS sort of thing. You would have to then rewrite it to, you know, through the rules, but you could, you could provide some syntax for this actually, where you say like, Hey.
00:25:50
Speaker
I don't know. I would have to think about the API for this, but you could definitely write something through post CSS, transform it to provide the name and you would be doing something very bespoke and weird, but you know, we're all about bespoke and weird things. And that would be a have your cake and eat it to situation where the people like you who are like, Hey, get your L and R is off my socks. I'm like, that's fine, but make the socks, but give me.
00:26:14
Speaker
an abstract function resolver factory. So I can say new socks with a constructor of L and R and you're like, you know what? Fine. I get mine. You get yours. We're, we're happy here. So like, I feel like that's a world that we could live in.
00:26:30
Speaker
Yeah, there is kind of a problem that shows up. It's like you want it to be portable, so you don't give it a name. But you're like, what if I want both? What if I want it to look anonymously if it didn't find this one? Which I think is actually how it works in general. If you said at container and gave it a name and it didn't find it, it has to resolve at some point. And I think it falls back to the page. But it would be cool if you could give it a list. Maybe you could do a comma-separated list, like look for this name. If you can't find that name, look for this name. If you can't find that one, then do nothing.
00:27:00
Speaker
Because then, yeah, we get to be explicit about which moments you want this in, which containers you should change. But if you're in none of those containers, do something smart still. That's a good idea. All right. Now, I want to move on to the units, because I feel like this might take a hot amount of time.
New CSS Units
00:27:21
Speaker
Because there are many units. And they, let's see here, we got, I have a whole list of them right here. We have CQMin.
00:27:29
Speaker
Uh, actually, can you see C C human? Like, is that for like a spice you want to cook with a, Hey, do you see my human? Yeah. I just put it in the dish. Good for taco mix. It's pretty much for taco mixes. It's grand. So dorky. I like it. So, uh, how about this? Let's go back. I have a list. So let's see. You, you should be able to do this. I'm going to start with CQ men. Can you do another one?
00:27:55
Speaker
CQ max, CQI, CQB, CQW, CQH. Yeah, you got them all. Okay. I was like, I think that's it. I just wrote an article on this, so they're fresh in the brain. Yeah.
00:28:11
Speaker
I understand, uh, I understand a lot of the, the definitions of them. So like CQI is, uh, inline size. So we are query inline. Yeah. To help you memorize the CQ. Yeah, exactly. And CQB would be block size. So with, so, uh, sorry, I mean height. Um, and then, uh, CQW and CQH are width and height, and that's more so not logical property version of that.
00:28:38
Speaker
And then we have CQMin and CQMax. Now, let's first start with, why would I use a container query unit over another type of unit? And then at what point, and from there, how do I select those from that?
00:28:57
Speaker
Nice, yeah. So one of the reasons that I personally use them is that the percentage unit can be really frustrating in CSS because it changes based on where you use it. If you use a percentage on a font size, if you use percentage on the left and the right of margin and padding, it can resolve either to the height or the width of the container. It gets kind of wiggly. So percentages are wiggly, and often you want to split a container in two.
00:29:24
Speaker
And so you can take the guesswork out of it by using CQI at 50 CQI. Now, you know, this is 50 of the inline size. You don't have to do 50% and be like, uh, guess, uh, same thing with blocks. So if you want the height, so you can be very explicit and deliberate about which one that you want, which is, uh, yeah, you're not leaving it up to CSS is resolution. Uh, you know, 20 years of resolving percentages issues. Yeah.
00:29:52
Speaker
And so when it comes to selecting a container query unit, so we have container query units in general, because it is based on where we're getting relative to the size of a certain aspect of a certain metric of a container.
00:30:08
Speaker
So that's either the inline size, the, you know, the block size or the height and the width. And what we're saying is, is that whatever property you're, you know, or whatever unit, your property, you're setting this, that accepts this unit, you're going to base its value on.
00:30:25
Speaker
the inline size or the, you know, the block size of that. And so that is, and that will change, which is very much getting into how container queries can be very mind bending is that that's going to change based upon the container size. So this is very much a way to scale up a size, scale down a size relative to the size of the container. Do I have that right?
00:30:46
Speaker
That's correct. And I have a question for you because in it with a container query at container, we have the option to specify a name or not. When I say 50 CQI, I don't get to specify a name. So which, uh, where does it resolve against David? So well, what, give me a property like 50 CQI. Let's do a width is 50 CQI on a button inside of a card. Uh,
00:31:22
Speaker
Uh, so we have 50 CQI on the, on a button's width inside of a card. So it's saying that the width of the button is going to be 50 container units or, you know, let's just say, I don't want to say percent, but I want to say percent, uh, 50%, uh, half, there we go, of the card, uh, the cards, um, width or the inline size.
00:31:42
Speaker
I feel like I'm in a spelling bee. I'm like, can you use it in a sentence?
00:31:53
Speaker
That's another proxy. I'm going to be quiet. You have to do logical and this and that. What if the button is now inside of a section inside of the card and the section is not full width on the card?
00:32:08
Speaker
Gosh. All right. I'm like, the files are inside of the computer. And, uh, so we have, so we have a button. I have to, I have to break this all down. So we want to get this right. So we have a button whose width is 50 CQI inside of a section now, or inside of a card that's inside of a section.
00:32:33
Speaker
Uh, no, I'm trying to add another layer of indirection. Right. I'm trying to, it's a button is now two levels deep from the card and it's like two levels deep in the card. Okay. Yeah. The kind of, the question is, is gunning at is does CQ units care about a container type or do they just go to the nearest container regardless of the presence of container type on there or not?
00:32:58
Speaker
believe it or not, that's what I was going to ask you. I was going to say, does it go up to the nearest container? And I was going to ask you, is there another container set? Um, because CQ, because from what I understand about them is that they will look for the, do that, did that really fancy word that you use the recursive parent container.
00:33:18
Speaker
And it will, from what I understand, they will do that. They will look for that one. And if they find it, they will base themselves off of that container, that named container or just a specified container. And if it does not exist, they will effectively act like viewport units.
00:33:40
Speaker
do I have that right? I am asking because I'm not sure. That's why I teed it up. I was like, I don't know if he knows the answer because he's going to be telling me right now. I'm trying to look it up. I'm like, do they, to the dimensions of a query container. So it sounds like they do need to find
00:33:57
Speaker
It sounds like they do recursion, but I kind of thought that you could use them anywhere. You can't use them anywhere, but I think that they go all the way. I think they fall back to viewport style. Yes. Which is effectively what you, which I guess really makes sense now because that's, I don't know if that's related or if it's just sort of like the distilling down the concept.
00:34:20
Speaker
But if you create one container query on the HTML or the body, like we were saying before, it acts like a media query. And so if you don't have a container, CQ units acting like viewport units make sense because viewport units are effectively media query units. The media query is on the viewport, viewport units, they're on the viewport too.
00:34:49
Speaker
So that's wow. Wow. That to me makes sense. You're muted and you're muted. I am muted. Okay. Here we go.
Resolving Container Queries
00:35:03
Speaker
So I'm, I'm, I'm building a little demo. So I've got a card with a section and a button and the button's going to be, uh, with the 50 CQI. Okay. So right now I can see that.
00:35:18
Speaker
It is filling the section, which is 50 width and the card. It looks like it's falling back to a viewport unit. So then if I give this card container type inline size, okay. Now it's 50% of the card. And if I give it to the section.
00:35:39
Speaker
Okay, so it's as we have described. It is just like a container query in that it is going to recursively crawl parent nodes looking for container type to be defined so it can resolve itself against that thing. But yeah, container query units though, you don't get to specify a container name. So it's always anonymous, which is a good thing to know.
00:36:01
Speaker
Right. That makes sense to me because it's latching on to the nearest container and there could, and that could be based upon a named container, but that to me, it makes sense to me that container query units are nameless. That to me is, uh, yeah, that gels. Um, now the two I didn't cover, what are CQ min and CQ max?
00:36:21
Speaker
Those are just like viewport units where they're going to look at whichever is the smaller. So if it's like a thin but wide or it's like a short but wide element, then the CQ min is going to be the height and the CQ max is going to be the width. But if you've got a skinny but tall element, CQ min is going to be the width and CQ max is going to be the height. So they help you kind of pick
00:36:42
Speaker
Almost like Cover and Contain, where Cover will choose the larger size for the object or the image to fit, and Contain chooses the smaller. CQMin, CQMax, ViewportMin, all these do very similar behavior.
00:36:56
Speaker
All right. And the last thing I want to cover and maybe the most important thing is using container queries.
Advanced Uses of Container Queries
00:37:05
Speaker
It's to me, container queries have been so hyped up. And like I said, for good reason, but the funny thing that is, is we distill down what we're using continue container queries for it's cards.
00:37:16
Speaker
Cards, cards all day, every demo. And what I think is funny too is I work on Firebase and I have worked on Firebase for almost 10 years. And I need to stop saying that. I feel like in every podcast and interview, I keep telling people that and we're like, we get it. It's been 10 years. We got it. We got it. But the funny thing is, is I've always said this in my time at Firebase is that everything is a, uh, everything is a to-do app.
00:37:42
Speaker
everything. So if someone, so like, cause I'm always creating app demos and someone's like, Oh, well chat apps, not a studio app. And I'm like, yes, you are. You're just chatting about what you have to do. And I'm like, well, what about like a grocery list app? I'm like, it's a to-do app, but, uh, or it's, uh, it's a to-do app, but pretty much it's, um, a to-do app for sure. Yeah. Yeah.
00:38:01
Speaker
Or you could flip it around. Everything's a chat app. I'm just chatting about what I have to do. But that's basically every app in the world. Now I've come to think, are we just doing cards because every single component is really just a card component? Well, Dave Rupert says that a card is just a mini website. So really what we're saying is a container query is just a mini website query.
00:38:23
Speaker
Exactly. Everyone's like, listen, not a container. This is not a card. This is a calendar. And you're like, well, what about the calendar is a big card. And then the, each day is a mini card. And it's like, Oh, okay. Like I feel like I could look at anything on a website and be like, those are cards.
00:38:41
Speaker
Like I, so I feel like that might be why, but in our attempt to try not to just talk about cards, I came up with a few things that I, you can use container queries for, uh, that are not cards, but probably are. So.
00:38:57
Speaker
My first is, is that I can see this going very, not to see, I've done some demos where I see this going very well with grid layouts. Because if you would take a, if you take a look at, uh, a grid column or just take a look at your most simple, uh, basic website layout where you have three fourths of the page is the article or the main or whatever. And then to the right, you got the aside.
00:39:21
Speaker
And that aside is tall and skinny on a full viewport. And then as the viewport shrink, shrink, shrink, maybe you want to stack that card below that, uh, that big width. So everything stacks below or maybe it stacks higher, but then an interesting dynamic happens in that like weird tablet size one where now it's not tall and skinny anymore. It's it's big and short. Yeah.
00:39:47
Speaker
And the viewport is not helping you out there because the viewports like you got 800 pixels of viewport and you're like, Oh, okay. And so then you're, then you're writing rules that are kind of weird because you're like, okay, be tall and skinny at this point. But then now at this point, go do something else. And so you're retargeting this. Whereas with the container query, you're just saying, Hey.
00:40:06
Speaker
When your width is this much, you're going to be tall and skinny. And you're going to do this thing. Well, you're going to be tall and skinny because the grid's going to make you tall. But like, hey, that's what's going to happen. And then as your width increases, well, now you can put all this other stuff over here. And so you're not thinking about where it is in the terms of the viewport or where it turns in the grid. It's just saying, hey, when I have this kind of space, Mike, this column is going to extend this way.
00:40:33
Speaker
But that column is probably a card. But that's how I see it. With grid, I think container queries are really good. Adam, what's your non-card example? Well, yeah, I just had a grid demo I did last week. It was called the Always Great Grid. It was like a bento box example that if it had two items in it, it looked elegant. If it had five items, which usually has that little cliffhanger at the bottom that's all weird shaped,
00:40:58
Speaker
and I handle it and I make it look pretty and I'm like, this grid handles any number. The other thing I added though, was a container query for aspect ratio, so that if it was wide,
00:41:09
Speaker
then it did a different bento than if it was portrait. And that was the first time I've ever done container type size, because I could then write at container aspect ratio is equal to portrait aspect or its orientation. I could say at container orientation is portrait. I queried something. Actually, I think I used aspect ratio. Who cares? Anyway, you could find out like, is this thing in landscape or portrait and adapt to it. So, uh, container queries kind of go beyond just width and.
00:41:37
Speaker
They are especially good for grids. I think they're also especially good for grids because grids generally you define a size of your columns and your rows, which is kind of clutch. We skipped over this already. One of the biggest book on container queries is you give something a container type and it collapses and it becomes five pixels tall. And you're like, what did you just do? And it goes, well, I can't be sized by my children anymore. I'm so sorry. If you're going to query me, I don't, I don't know. Now I'm dumb.
00:42:05
Speaker
And you're like, dang it, you're dumb. I have to tell you more about, about the world so that you can have a size. And anyway, um, and then grid is like, Oh, no, no, I got you. I go grid. Yeah. Fit into this cell. And it goes, Oh good. Now I have heightened width again. Yeah. That's true. It's true. Something that if you are, I'm commonly using everything with grid. So I kind of one of the things to get those, you kind of get that for free when you're doing it, but it's true. If you're doing an isolated, uh, one that's going to be like, I'm going to try a container queries. And then it's going to be like,
00:42:35
Speaker
You're like, this is good.
00:42:41
Speaker
I usually make a dummy node. I even had a thing that was called a contain dash nerd. Uh, so that was like a container. Uh, element. It was just like, anyway, whatever. Okay. I think you got it. And that's all it did is would have a name and a type on it. And the name would match the like stupid tag name I gave it or whatever. And that was nice because then the collapsing happened at a very specific wrapper node. It was like container query or wrapper node.
00:43:06
Speaker
And then I didn't have to like intermix my grid layout with trying to handle the fact that it's container. And then my grid container can query its parent because it's parents, just a dumb thin outline of space. And anyway, that's, those are a couple of my hot tips is container queries are great with grid. And it, it can be really nice to have a wrapper element that is just the container to be queried. Okay. Well, the last one I'll give is.
00:43:31
Speaker
font scaling, you can use container queries to scale up font. And that might be the least card specific one that we got, you know, cause you can, you don't need to put text in a card.
00:43:44
Speaker
So even though our website's a card, so, okay, well, you know, but that's it font scaling. I, you can use container queries for font scaling using container query units and everything to, as the, as the not card grows and it's with, you can scale the font up nice and easily. It's kind of like a different way of doing a clamp function. Uh, so it's, it's, I like it. Uh, so well, that is container queries.
Conclusion: Embracing Container Queries
00:44:10
Speaker
We have, uh, they are easy. They are hard. They are good. They are bad. No, they are good at it. They are good. We have bad. And I very much, I think that one of my risks, I, we did our resolutions pod and.
00:44:26
Speaker
One of your resolutions was to use container queries for anything but cards, uh, or not cards. I am going to have another resolution now to just use container queries in general. I'm going to move away from media queries. I'm going to make that break. And I'm if nothing other than just putting them on the body and just saying, you know what? This is, this is where I'm starting. You got to start somewhere in the container query space and start on the body and then just move your way down. So.
00:44:53
Speaker
That's sweet design you got for a new site. You're building us a new site. You can just container query from the ground up there. It won't be, man, this is one of those things where it's like, it won't be a new site. If, uh, to everyone listening to this, if it goes according to schedule to the existing site, that's awesome.
00:45:13
Speaker
Well, that's it for this episode of the bad CSS podcast and give us more stuff that you want us to cover or what are you using container queries for? Because, you know, and not carts, uh, or just say carts, you know, that's fun too, but let us know. And if any topics you want to cover, but if not, we will see you on the next bad at CSS podcast. Smell you later y'all. Woo.