0:00
So you just finished coding up a really cool looking card
0:03
It's fully responsive on all different screen sizes. You go ahead and show it to your boss and he's like
0:07
oh, that looks really good. Why don't you add one to the sidebar? So you're like, no problem, I can add that to the sidebar
0:14
It's fully responsive, right? You add it into the sidebar and, ah, that looks terrible
0:19
That's because media queries just aren't enough for responsive design, which is why I'm so excited container queries are finally a thing
0:26
because with them you can solve this problem so easily. Welcome back to WebDev simplified
0:34
My name's Kyle, and my throat feels like I ate 100 pounds of sandpaper for breakfast
0:39
so if I sound like a dying walrus, I apologize. So for this video, we're going to be talking all about container queries
0:44
and as you can see over here, we have a fully responsive card. As my browser, so I as shrinks down
0:48
we can see that this card transforms into a vertical card versus a horizontal card
0:53
And on the left side of my screen, the main content, you know, these cards transfer at about a good point
0:57
Once they become, you know, start of unreadable, they transfer to this vertical format where it's much easier to see what's going on
1:03
But this sidebar, which is much smaller than the main content, obviously looks terrible no matter what screen size I'm on
1:08
unless I'm on a small enough screen size where it shrinks down to this other form. So with Media Queries, the only way you can actually determine the size of elements
1:15
is based on the entire size of your screen. For our example, whenever our screen is less than 800 pixels
1:21
we use this vertical card component. When we're above 800 pixels, we use this horizontal component
1:26
Now, obviously, this is not ideal, but this is all we've had for the longest time when it comes to CSS
1:30
and it's been good enough for most things. And in these cases where we have this sidebar
1:34
almost always what you would do is you would just go to your HTML, you would add another class, then you would have a sidebar card that you would modify the size of
1:41
to make it smaller because it's in a smaller component. That's a huge pain
1:45
It's kind of complicated, which is why container queries are so amazing because instead of being forced to just use the viewport as you're sizing
1:52
you can use any element on your page as a container, and then that container can have its own widths that you use media queries off of
1:59
So in our example, let's just say that we're going to go back to our HTML here. I'm going to show you what my HTML looks like
2:05
All we have really simply is we have a main element here and we have an aside
2:09
The aside is our sidebar, and the main element is our section that has these different cards
2:14
Essentially, these are containers where I have my cards. For example, I have a sidebar container which contains information
2:19
I have this main container which contains information. What I want to tell my browser essentially is that this main element
2:25
is a container and that this is side is a container and then whenever I have my card inside of any
2:30
of these different containers as that container changes in size what I'm going to do is going to
2:34
change my breakpoints for that so what we can do is we can just say we're going to select our main
2:39
as well as our sidebar and I want to set these as a container so to do that you're going to need to
2:43
spit a container type and there are two different types you can use there is the size type and the
2:49
in line size type in our case we're going to use the inline size and I'll explain a little bit why that is
2:54
So by click save you notice nothing at all changes on my page and 90 of the time when you set an inline size nothing should change on your page But now I have the ability to do container queries So instead of using a media query I going to use a container query
3:07
So I just replace media with a container and now that's going to work exactly the same as a normal media query
3:12
But instead of measuring the size of my screen, I'm measuring the size of my container
3:16
So now in my case, when my container is 800 pixels or more, I use the horizontal view
3:21
Otherwise, I'm using vertical. Now obviously, this is a bit too wide. So I'm going to swap this down to about 500 pixels
3:27
So now, when my container is 500 pixels or less, it's going to use a vertical form
3:32
So my sidebar, which is smaller than 500 pixels, is using this vertical form
3:36
While this left side, this main content, it is greater than 500 pixels, so it's using the horizontal form
3:41
As I shrink my browser down, you'll see at one point, the sidebar and the main content are both going to be less than 500 pixels
3:47
and now you can see that both of my cards are in that vertical form on the left and right-hand side
3:51
Now, this right here is incredibly powerful. It allows you to make sure you can resize things based on the container instead of the
3:57
full browser with which is really nice, especially when you're doing things with components
4:01
So if you're working in something like React, view, or Svelt, it makes writing those components
4:05
so much easier, since now it doesn't matter what that component is inside of, you can size
4:09
it based on its container and it's going to be the exact size you need and the exact orientation
4:13
for your responsive design. Now before I start diving into some of the kind of cool things that you can do with containers
4:19
I first want to just talk about how containers work and what exactly they do by talking
4:23
about this container type property as well as some other properties related to containers
4:27
So the container type, you can set inline size or you can set size as the type. Those are
4:31
currently the only two types that you can set for this. And what this essentially does is it
4:35
determines what does your container represent? Like what type of sizing are you going to determine
4:40
based on your container? With an inline size, you're saying that you only care about the inline
4:44
size, which by default is going to be your width. You're saying, my container defines its own
4:48
width. The children have nothing to do with the width of my container. That container
4:52
width is determined by the container itself. Then the children are going to just be
4:56
inside that container. If you do size instead of inline size, you're now saying that both the
5:01
height and the width, both directions are determined by the actual container itself and not
5:05
by the children. This is a little bit of a problem. We can really easily see this by if we
5:10
have our sidebar. I'm just going to select that class. Let's just add a background color
5:15
here of black. There we go. And what I'm going to to do is I'm just going to remove my container type for now, and you can see on the right hand
5:21
side of my screen, we have a black background over top of our sidebar. But when I change my container type to size, that black background disappears, while if I'm
5:29
in inline size, that black background is still there. The reason for this is because when you specify size, like I said, you're saying your container
5:37
determines the height of your content. In my sidebar, nowhere am I mentioning the height of my sidebar at all
5:43
So this height essentially just defaults to zero. Now, if I come in here and I specify height like 200 pixels
5:48
now I'm going to have a 200 pixel black box that determines my actual sidebar
5:52
But 99% of the time when you're working in web development, the width is going to be a thing that determined by the container whether it just a full view width or it going to be width based on a sidebar or main content Essentially the width is always something you kind of take into account and determine on your own But the height is just something that happens
6:09
Whatever the width of the content is, however it stacks, that's usually what the height is. It's usually based on the children inside that container
6:14
Which is why 90% of the time you're going to be using inline size as your container type
6:18
since you want to size things based on width and you don't care about sizing things based on height
6:22
Now if we do that and we can remove this hard-coded height, you can see our sidebar goes back to working as before
6:26
Another really cool thing you can do with containers is you can actually name them. Because the way containers work by default is whenever you have an At Container queries
6:34
for example, our card here, what happens is it looks for the first container that it's inside of
6:38
In our case, it's inside of this main container, and that's the one that it uses for its sizing
6:42
Even if it was inside of another container, it would just ignore all the other containers. It would only choose the closest container to itself
6:48
But you can specify a name. For example, I can come in here. Let's just have our body have its own container
6:54
We'll say container type in line size. Now we have two separate containers
6:59
One is the body and one is the main content. And by default, everything inside of here is going to be inside the main or sidebar first
7:05
So it uses that container. But we can give our body a container name
7:10
Let's just call it body. You call it whatever you want. And now when we specify our add container, we can pass it a name
7:15
In our case of body. And then what we want to do is we'll say dot card, background, red
7:22
And now if we just specify some type of thing for our actual query, for example, we'll just say like max width is a thousand pixels
7:32
I save. You can see now when my container is 1,000 pixels or less, my background color is showing up as red
7:37
And if I increase this, eventually the background color will go to white because now we're greater than 1,000 pixels wide
7:42
The place that this is really useful is when you specifically want to be inside of a certain container
7:47
For example, if I want to do things based on my sidebar, I come in here, I could say sidebar
7:51
All this are sidebar container. Same thing down here. I could say sidebar
7:56
And then now only the component in the sidebar is going to have that red background color
8:00
So it allows you to have a little bit more fine tuning to select the exact container you need
8:04
Honestly, though, most of the time you're probably not going to need a container name because you're going to be specifying the exact container you want all the time
8:11
And it's going to be like the direct parent. So you don't have to worry as much about using the container name
8:15
But when you're deeply nested, you may want to specify a certain container, which is where the name properties really use
8:20
Now, another really useful thing you can do with containers, let's just remove all this extra
8:23
sidebar stuff we don't care about, is you can actually use container units. And container units work just like viewport units
8:29
They're all the exact same type of units. They just start with CQ instead of VW or VH
8:35
And these container units are going to determine the actual width and height of your container
8:40
And if you're using an inline size like we are, you only have access to the inline-based
8:44
or width-based units. But if you're using the size property here instead, you can access both high
8:50
height and width of your container. But most of the time, like I said, we're going to be using inline size
8:54
So let's see exactly what that's going to look like. Let's select our card. And what I want to do is I want to change the width here to be 50 CQW When I save you can see what happens is all of my cards get changed to 50 of the width of my container I could change it to like 75 and now all the cards are 75 of the width of the container
9:11
This is really great if you need to size things, obviously, based on the container. And the nice thing is, like I said, you have access to all the viewport units
9:17
They all are the exact same. It's just instead of starting with a V, they start with CQ
9:21
And if you're curious about the different types of viewport units, I have a video on all of them. There's way more than you think there are
9:26
It's going to be linked up in the cards and description for you. Now, let's say, for example, our card
9:30
was not inside of any container at all, what would happen with these container units
9:34
Well, if we remove this container and we just give it a quick save, you'll see that essentially what's happening here is that the container unit is just defaulting to a viewport unit
9:42
So if I change this to 50, you can see that all of my cards are 50% of my viewport because
9:47
by default, the container that you're inside of is going to be the viewport because there is
9:51
no other container available other than the viewport. By default, these just fall back to viewport units
9:56
Otherwise, if you are inside of a container, it's going to use your container's actual sizing. Now a couple other things I want to mention about container queries is if we just inspect
10:04
on our page right here, we'll pull this up, you can see that when you're dealing with containers, that inside of your CSS, you're going to have these container sections. And I can click on this
10:11
container button. And what it does is over on the right hand side, you can see this purple outline is perfectly outlining what my container is. So I have this purple outline around my
10:19
entire container, which will help me with debugging to make sure my container is what I expected to be
10:23
and is the size I expected to be. So this is really useful to be able to debug these different
10:27
things by just clicking on these buttons. I mean, okay, here's my two different containers. Another really useful thing that you can do is let's say that we want to always have the parent
10:35
of an element be its actual container. Well, let's just get rid of this code here real quick
10:38
What we could do is we could say that we have our card and we know that we want the parent of this card to always be a container for us
10:44
We could just give this a quick has property. This is essentially like a parent selector
10:48
I have a full video covering out. I'll link in the cards in description for you. We can just write a simple line of code like this
10:54
And we can copy over our container type, paste it down here, get rid of our old code. Now, if I just give this a quick save, you're going to notice we get the exact same result
11:01
It's working exactly the same as before, and all of our different sizing is working for all of our different viewport units and viewport sizes
11:07
The reason for this is what this line of code is saying is, is select an element that has a card as its direct child and make that a container
11:14
So every single element that has a card inside of it as its direct child is going to be set as a container
11:20
So that way, our card is always going to have a container that's inside of it, and that container is always whatever the parent of that card is
11:26
Now this is great if you just want to have this happen automatically, but a lot of times what you may want to do is you may want to in your HTML, just wrap your element
11:34
For example, here's our card. You may just want to wrap it in a div so that you can really easily control what the size of this div is going to be because sometimes the parent element may not be the size that you expect it to be based on
11:45
So sometimes it's best just to wrap it in an additional div. And that additional div is now going to be your container
11:50
And you can even specifically, you know, like give it a class of container or something to give it that container styling
11:54
Now, if you're interested in checking out that really cool parent selector that has selector
11:58
I have a video on it linked right over here, as well as if you want to see how to create the cards from this video
12:02
I have a video on that also linked over here. With that said, thank you very much for watching and have a good day