CSS Fundamentals

Container Queries

CSS Fundamentals

Lesson Description

The "Container Queries" Lesson is part of the full, CSS Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Kevin introduces container queries, showing how they adjust layouts based on container size rather than screen size. He demonstrates their use, explains the need for defined containers, and highlights their advantages over traditional media queries for creating dynamic, responsive designs.

Preview

Transcript from the "Container Queries" Lesson

[00:00:00]
>> Kevin Powell: All right, container queries are a new CSS feature that I was debating whether or not to include in this course because they feel like they're a little bit more advanced, but being, I don't know, it felt like a disservice not to include it in here because they solve a very big pain point that you can run into when you're using media queries. And I'm going to use this demo that we looked at earlier, the one that we created together with our template areas as the example of this.

[00:00:26]
Before we dive into that though, just really quickly, a container query looks a lot like a media query. Instead of media, it's at container. Nothing else different, so they work in the same way, you're putting widths in there. Container queries only look at the size of things, they do not look at all those other things that media queries can look at. So just to throw that out there is one of the big differences between them.

[00:00:52]
The reason that things can break or that media queries might not be what you need, or even this case it's not necessarily a media query. But it seems like I broke my grid. Oh no, we didn't. OK. So for this example where we created this layout that we did last time, we said it's small sizes, we wanted it to be like this, and we used a media query to rearrange what it looked like at larger screen sizes.

[00:01:16]
Yeah, that's perfect, that's exactly what we wanted. But now I've included these in a grid, and I'm using the auto grid that we already created before. So at one point this is going to go up to two columns. The space got small again. But we're at a big viewport. They're not going to change, even though they don't have the space that we wanted them to have for it to actually be a two column layout.

[00:01:39]
And at one point this gets up to three, if I zoom out a bit, and like you can really end up with a bit of a squished scenario where these cards don't look so good all of a sudden. We spent all that time making those grid template areas and all that hard work sort of goes out the window, and it's kind of annoying. That's the advantage of a container query. A container query can look at how big the container of the element is, and you can adjust it on that instead of looking at the total size of the viewport.

[00:02:04]
But there's some catches that come along with them as well. This was actually thought to be impossible, and a big thank you to Miriam Suzanne, who was one of the pioneers that helped solve the problem in getting this and writing the spec for container queries. And it was through something called CSS containment that we're definitely not getting into that actually made it possible. The big catch with it though is if I come down here and I say at container.

[00:02:37]
Now, this is never going to work. These styles aren't coming in. Because the container can't find or the container query can't find a container. And one of the limitations of using container queries is for them to work, we have to have a defined container for them to see the size of it. There's really complex ways that we could build around avoiding adding to our HTML. I'm not going to suggest that because it gets complicated really quickly.

[00:03:08]
The easiest thing to do is just to wrap every element within an extra layer. It's a little bit annoying to have to do this, and this is only a limitation if you are using intrinsic layouts, so. To know the size of the cell, when we go up to two columns that this profile is living in, I'm going to come here. Oh, I already did this one actually. I've created this profile container. So originally we didn't have that, we just had our profile.

[00:03:38]
Like that, and we can wrap it in a profile container. The div doesn't, we don't see this extra div there, it's just holding all of the content, and it feels a little bit strange because we have a profile container and the profile, they're both just holding the content that's there. The advantage of having this extra layer on the outside now is we can use container queries. Because what I can do is dot profile container.

[00:04:08]
And we tell it that it's a container. To do that, we use container type. And we come in, there's two options here. I'll do the first one and see if it breaks everything. I think it will. I'm assuming, yeah, look, the first we lost the card. It's there, it's behind it's you can barely see it sticking out the top. You're very rarely going to use a container type of size. Instead, you're going to use an inline size.

[00:04:38]
And now it fixed our layout. The reason the container type size broke the layout is the way container queries are made possible, is it says the children have no impact on the element being the size that it is. So if I say container type of size, it means the children are no longer defining the height of the element. But that's what the default behavior is. So as soon as the children aren't defining the height, it just goes to a height of zero and it breaks.

[00:05:04]
There are potentially a few use cases for it, but they're few and far between 99.9% of the time you will be using a container type of inline size. It's just saying that it's looking at the inline size of the container, and as we know, the inline size is never defined by the children. The inline size is being defined as the auto width, which, perfect. That means it's just filling up the entire space.

[00:05:31]
As soon as I've done this, we have a defined container for my container query to be looking at. So now the layout's working, it goes to two columns. And then, when the size gets smaller again, it drops back down to being one column over here. So we go from, I think I broke something within my other layouts, but oh, because I haven't defined containers in these other ones. So this first one at the top has the defined container, so if it's a wide container, it can do the large size.

[00:06:01]
If it's a narrow container, it can do the smaller size again, and it can adjust to the different situations that you're throwing it in. So this could be something that's a three column layout, but that component might be getting put into a sidebar. All of a sudden you don't want it to be three columns when it's in this small space. Your sidebar becomes a container type inline size, and you can use a container query instead of a media query, and then your layout will adjust.

[00:06:28]
It'll always stack in one place, always be three columns if there's enough space. So let's fix the other two just so we're clear on how that's working. On the outside, you need the defined container, so I can have my div class equals profile container. Whoops. And then make sure that closes all the way down here. On the outside is the profile container, all that's doing is saying, look at how big I am.

[00:07:03]
Nothing else. And now this element here is able to see the size of this. So once again, we have our two column layout. We're dropping down, it's stacking this way. Fixes itself and then when we get to the narrow columns again, it goes back to being what it is because the container that it is inside of is becoming smaller. It's a little bit annoying because every time you're using them, you're very often going to have this pattern of something container and then the element inside of it.

[00:07:35]
Going back a little bit, it's why I've stopped using the class of container for the max width on things and I'm using a class of wrapper now, just not to have that confusion between what's going on. And for a little while, I was using just a container with nothing else, like dot container, class container, but I was like, well, people are getting confused because they think that's the classic container that my wrapper is now.

[00:07:58]
So I tend to actually call them something like card container or something else if that's all it's doing, just so people don't get confused about what the purpose of it might be. There's a lot more that we can do. This is a very brief overview of container queries. I just wanted to show that that's possible with them. If you'd like, I have a video that dives into comparing media queries and container queries a bit more in depth.

[00:08:21]
Another video of mine here that looks at more advanced use cases of what we can do with container queries, and I've included a quick start guide to container queries, a friendly introduction to container queries, and a container queries unleashed by Josh Comeau, those are really cool interactive articles, and an interactive guide to container queries by Ahmad Shadeed here as well, just because I know this was a very brief introduction and it's something that people could definitely deep dive a lot more to see the other things that it makes possible.

[00:08:58]
I guess my knee jerk reaction then is like, wouldn't you just always use container queries? So I didn't talk about it. There is a side effect to defining something as a container. For most layout things, you'll be OK with them, like the side effect isn't that big of a deal, but it does because of the way CSS containment works. I think it creates a new stacking context. It creates a new, we're going to be talking about those for anyone who doesn't know what they are, creates a new containing block, I think as well.

[00:09:26]
So there's like a few things that all of a sudden might throw it off from how you're using it. I've also heard like there's been a lot of people who have said, we like container queries is this big thing that every developer wanted, and then people have got them and been like, oh, it doesn't really work for what I want. And they just went back to using media queries. Part of it was, well, now I have to take that extra layer of wrapping.

[00:09:48]
I'm like that's not that bad, just to put it one more div, not the end of the world, but some people, just the patterns they're used to using, it didn't quite deliver what they were hoping. I think the big thing too for me with container queries, I was like, it helped solve a few of those problems like the one I just looked at. But if you use them only like media queries, they're like this is cool, but I don't really need it everywhere.

[00:10:17]
Like the media query is actually working pretty good except for these few situations. One of the advantages, I'll do a quick one now, but one of the advantages with container queries that you can't do with media queries is you can actually, the size here that you're looking for can look at, it's aware of everything, like media queries, if you did a, if you did like rem here of, I don't know, 50 is probably too big.

[00:10:47]
If this is on a media query, the unit isn't even looking at what your rem font size is, like the HTML font size, because it's global, so it's actually going to the browser's default font size. Container queries are aware of this. So you can do things like this, where you're using smarter units. I've done a lot with like ch, so ch is the width of a character, so I'm changing it based on once the line length is 40 characters long, it gets a little bit more interesting.

[00:11:23]
We were speaking about Piccalilli earlier, Andy. I'll see if I can find it really fast. I can never spell Piccalilli. Piccalilli, reality check. I think it's this one. Yeah, it was this one. I just see, I'm going to scroll really fast here. This is the first time that I was like, oh, container queries can do more than what media queries can. The container query, he's actually basing the container query on the width of the container versus the viewport.

[00:11:51]
So as he had a two column layout that would, it was stacked and then it would switch to a two column layout. So if it went to a two column layout, this wasn't working anymore, so like. The fact that you're not only looking at the viewport, you can compare the element to the viewport size now. It opens up some interesting things. We don't have time to dive through this on the practicality of it. I think there's a working example here.

[00:12:15]
So yeah, here, it was just like the way that the image is changing size and a few other things as the viewport got bigger, was what he was doing. So it based it whatever way his layout was, the element could react to that. It knows if it's stacked or not because it's passed a certain viewport width. It just opened up this new door for me in using them, so, well, if possible, include that, but yeah, reality check by Piccalilli, it's worth a read just to get to that bottom part to it, it opened my eyes for a few things, but you have to start rethinking a little bit and not just thinking about the way we've traditionally used media queries before they start feeling a little bit more useful.

[00:12:45]
Because they, yeah, they definitely feel like, oh, I'll use it for everything, and then you start doing it, and you're like, oh, maybe I didn't, it's not as cool as I thought it was going to be.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now