0:00
The cascade and specificity are part of what makes CSS so amazing, but also one of the reasons
0:04
it's so annoying to work with, but luckily that annoyance is going to be going away because
0:09
CSS is introducing something called cascade layers, which make working with the specificity
0:14
and cascade so much easier, especially when you're trying to deal with overriding styles
0:18
from something like a framework such as bootstrap or foundations, or if you're trying to make
0:22
small little utility classes that you want to have overwrite other things in your CSS, or
0:26
if you just don't want to deal with long complex selectors. This CSS Cascade layers is going to take care of all of that, and it's super simple to implement
0:37
Welcome back to WebDev Simplified. My name's Kyle, and my job is to simplify the web for you, so you can start building your dream project sooner
0:44
And in this video, I'm going to blow your mind with CSS Cascade layers. So to explain how they work, we first need to understand what a layer in CSS is, because it's something you really never had to worry about until now
0:53
So I have a simple HTML page that has a default button, and then it has two normal buttons
0:58
and this small button is just wrapped in a div that gives it a smaller size. And if we've got our styles here, you can see we have a button with normal styles
1:04
and then our small button just has a smaller padding in this other class. Don't worry about it for now
1:08
So to understand what's going on, let's inspect our page over here. And if we go over to our elements tab, we can click on just our custom button
1:15
Let's go to this button right here. And we can look at the styles being applied to it. As you can see, we have our button styles, which we've defined in our CSS
1:21
That's the exact same styles that are being applied here coming from our style sheet. And then we have this other section way down here
1:26
which has all of the user agent defined styles. These are the things that your browser puts in as the styles
1:32
And this is its own layer. So we have two layers here to consider. We have the user agent style sheet, which is our browser layer
1:38
And then we have our actual own authored styles. So these are the styles we create ourselves as a separate layer
1:43
And it's important to know that this user agent style sheet is the reason why buttons in Safari look different than buttons on Chrome by default because they have their own
1:50
user agent style sheet. But you'll notice, though, when you're working with CSS, you never have to worry about what the
1:56
default styles are because you can overwrite them always. You don't have to worry about what the specificity of the selector is. It's just always possible for you to overwrite them, no matter what
2:03
your CSS selector is. And that's because when you're comparing styles between two different layers
2:08
they don't care what the specificity is. All it cares about is how important the layer is
2:12
So the layers have essentially their own order of importance, and the more important layer
2:16
will always overwrite the less important layer. So like I said, if this button here has a crazy
2:21
specific selector, like an ID selector, and all you have is a class selector, even though a class selector
2:25
Even though a class selector is less specific, it's in your authored layer, which is more
2:29
important than the browser layer, so it'll automatically overwrite anything in the browser
2:33
layer. Now up until now, there's really only been two layers we have to worry about. We have
2:36
the browser style sheet, and then we have our own custom style sheet. But with the new layers
2:40
API, we can actually create our own layers inside of that author layer, and these layers
2:44
allow us to organize our code so that even if we have less specific selectors or more specific
2:49
selectors, that won't matter, and instead it will care about the layers of our actual code
2:53
So let me show you exactly what I'm talking about. I have this P1 class right here
2:57
It's a very non-specific selector. And what I want to do is I want to apply that P1 class
3:01
to anything to just give it padding. So if we come into our index, let's apply it to our button
3:05
We can say class equals P1. You can see it now it has a bunch of padding
3:09
Let's see the same thing for our small button, P1. You'll notice it does absolutely nothing
3:13
and we'll come in here with our custom button and you can see that applies correctly
3:17
Now the reason P1 doesn't work on our small button here is because our small button where its padding is being set
3:23
more specific of a selector than our P1. Now if you unfamiliar with specificity this video is going to be pretty confusing to follow so I recommend checking out my full specificity guide It be linked in the cards in description before you come back to this But that the reason P1 doesn work is it a less specific selector than this selector right here so it never going to apply
3:39
So it's never going to apply. But we can get around that by using layers
3:42
With layers, we can say, okay, you know what, we want our code for our P1 to be in a layer that is more important than the rest of our code, so it's going to apply over top of it
3:50
So let's look at how we can create a layer. To do that, we just need to use an ad selector, so we can say at layer, and then inside of this layer, we need to give it a next
3:57
We're going to call this utilities. And then inside of this layer, we just put all of our code, just like that
4:03
So now we have a new layer called utilities, which is where our padding is specified
4:07
And now if I say if you'll notice, nothing actually changes on the right hand side of my screen
4:11
And that's because any code that's not in a layer, for example, all of this code, will be assumed to be more specific
4:17
So always we have our layers, and then after that comes all of our non-layered code
4:22
So currently the way that our stack works is we have our browser style sheet at the bottom, the least specific
4:26
Then we have this layer called Utilities, which is the next most specific, and then we have all the code not in layers, which is going to be the next most specific after our utilities
4:35
So what we want to do is we want to make it so that our utilities is more specific than this base layer
4:39
So let's just wrap this in its own layer called base. Come in here, we'll say at layers, or at layer
4:44
We'll call this base. It doesn't matter what the name is. And we'll just come in here, make sure we have our spacing set up properly, and we'll save
4:51
And now you'll notice our padding actually properly applies to this small button
4:55
small button. And that's because when you define layers, they go in order from top to bottom
5:00
which is the least specific. So the bottom layers down here, utilities, is more specific than our
5:04
top layer base. So now we have four different layers really to worry about. We have our browser
5:08
style sheet layer. We have our base layer, which is our next layer. Then we have our utilities
5:13
which is the next most important layer, and then finally all the code not in a layer, which in our
5:16
example is nothing. But if we had code outside here, such as body that said background green
5:23
that's now going to change our background to green. And if we tried to change our body somewhere else
5:27
such as inside of here, to a background of red, you're going to notice that this one right here is outside
5:32
so it is technically more specific. Let's get rid of that, though, because it looks really ugly
5:36
So already having these different layers is great because you can take things such as utilities
5:39
that are going to be very small selectors, so the specificity is going to be very low
5:43
and you can actually make them override things with more specific selectors just because it's in a layer that is technically more specific
5:50
So these layers are a great way to kind of think about it as like another layer of specificity
5:54
where you can use a layer to determine where the specificity lies, and then everything inside that layer
5:59
is only compared against itself essentially, and everything outside of that layer doesn't really matter
6:04
Now this is great, and being able to find your layers like this is awesome, but a lot of times
6:08
you want to define the order of your layers at the beginning of your file to make it easier
6:11
to determine what the order is, because if I just take this layer utilities and now define it up here above my base
6:17
you can see that the padding no longer works, and that's because this utilities is technically less specific than every
6:22
everything inside a base. That's why none of my buttons, except for the default one, have the actual padding from P1
6:28
So if I don't want to rely on the actual order of my CSS, instead at the very top of my code
6:32
I can have my own at layer, and in here just put a comma-separated list of all my layers
6:37
in order. So for example, we could have base, and then we could have utilities, and then put a semicolon
6:42
at the end just like that. And now when I save, you can see even though I define my utilities before my base, up here
6:48
I said, no, base is the least specific, and then utilities is the next most specific
6:52
So that means that everything inside of this utilities layer is going to overwrite anything inside of this base layer no matter what the specificity is
6:59
I really like when using layers to have this one line at the very top of my CSS that just orders out my layers exactly how they going to be Now one place that this is really useful besides just within your own code is if you have a framework such as like bootstrap that you importing into your code
7:13
overriding those styles can sometimes be a huge pain. So being able to define all of your boot scrap code in its own layer makes working with it so much easier
7:22
So let me show you exactly how you would do that. We're going to create a brand new layer. We're just going to call it framework
7:26
This is going to be for all of our framework code. So this is like bootstrap or tailwind or whatever frame
7:30
work you're using, it doesn't matter. And then we can import that URL, so we can just say import URL, and I'm going to paste
7:36
in the bootstrap URL right here, as you can see. And you will notice that my syntax highlighting is kind of broken, and the reason for that
7:42
is because Viz code is not familiar with this layer syntax yet. It's very new, so it doesn't quite have support in VS code
7:48
If we just comment this out, though, you'll get that syntax highlighting back. I'll have that just so we can see what's going on
7:53
So right here I have my URL for the bootstrap I'm importing, and after that, I can essentially
7:57
pass it this layer, and inside of it, I can give it a name. for example, in our case we called it framework
8:02
So I can say, you know what, I want to import our bootstrap code and I want to import all of that code
8:06
inside the layer of framework. Now if we just comment this back in
8:09
now all of my bootstrap code is in its own layer called framework
8:13
And you notice that made quite a bit of changes, but if we just swap around framework to make it go after base
8:18
so I just come in here like this, you'll notice immediately that a lot of things about my button change
8:23
especially if I come in here and I just say, you know what, this is going to be like button danger
8:27
There you go, so it's going to give us that red color, or we'll change it to like button primary. So that's going to be the primary color for our button inside a bootstrap
8:34
And that's because our framework right here is overriding our base. If we swap these around again, though, and make our framework come first
8:41
Now you're going to notice that the bootstrap styles no longer apply, and instead our base styles are applying
8:46
And that's because of this specificity chain. It doesn't matter where the order of the imports are
8:51
whether I import my bootstrap code first, or whether I input my bases first
8:55
It does not matter. All that matters is the order of these layers here. And again, this makes it so much easier to override the default classes inside of a framework
9:02
because before, if the framework had very specific selectors, overriding them was a nightmare
9:07
but this makes it so much easier. Now, this right here covers the basics of layers, but there's a few more advanced concepts
9:12
that I want to cover. Firstly, is how you deal with not having to use imports
9:16
Imports in CSS are something I don't like because first you have to download this entire styles.cess.S.file
9:22
And then it looks for all your imports, and then it downloads the CSS inside of them. So if you have a bunch of imports, it's going to slow down
9:27
down the load time of your page. It's actually really easy to get around this though
9:31
We can just take this import code and I want to copy this out and inside my index HTML, after my style CSS
9:37
I wanna have another link tag, or actually I'm sorry, a style tag, and inside this style tag
9:42
I just wanna put that import code. And what this is going to do is since the CSS reads
9:46
or the HTML reads from top to bottom, it's going to get this style sheet, it's gonna see the style and do the import
9:51
and it's gonna download both of these style sheets at exactly the same time, because it doesn't have to wait to download this style sheet
9:56
to figure out it needs to download another. So now if we save, you're going to notice we get the exact same results by doing this as we did before
10:02
And again, we can swap this around. So this is going to be, you know, based and framework. And you can see that when I do that, it actually doesn't give me the same output as before
10:09
And that's just because I need to refresh my HTML page. If I just click save here, it's now going to work
10:13
And that's just because I'm doing inline imports here. And since I've changed my layers after the import, I just need to make sure I refresh that import
10:20
That's like the only downside of doing this, but you never really change the order of your layers in development
10:24
So you don't really have to worry about this too much. This is one way to get around that loading issue
10:28
Now we're going to talk about some more advanced features inside of layers. I want to pair down this code quite a bit
10:33
I essentially going to get rid of my entire base layer here I don really care about this Get rid of that And all we going to have is our framework and our utilities And inside of here for our buttons I just going to have that P1 class on our default button And that is it That the only
10:46
thing that we're going to have inside of here. And I'm even going to bring this import back, just so it's a little bit easier for us to see exactly what's going on. And we just get rid of
10:53
the style tag here. So now what we do is we have the single button and this button has our P1
10:58
utility. And now if I save, you can see something really interesting. My P1 utility is not being applied
11:03
to this button here. And the reason for that is that Bootstrap has its own P1 utility class
11:08
But you'd think, well, since Bootstrap comes before my utilities in the layers, the layer
11:12
should override it. Let's just inspect this and see what's happening. If we scroll all the way up here, you'll see that we have our P1, and the P1 for Bootstrap
11:20
is defined using Important, while our P1 is not. So let's try overriding our P1 by making it
11:25
important. That should fix the problem, right? Well, when we change it to important, you're going to notice it still doesn't work. And that's because when you're messing with different
11:32
CSS cascade layers, the way that important works is that whatever the CSS style sheet that
11:37
is defined in the earlier layer, those important are going to override
11:41
So since our framework is defined first, all the important keywords from framework are going
11:46
to override the ones that come later. So unlike normal CSS with the layers, everything dealing with important goes in backwards order
11:53
So the first thing is most important while the last thing is least important. So if you use important, you had to flip that specificity around
12:00
That's just one more reason, in my opinion, to know. never use important, it just makes everything more confusing and more difficult
12:05
So that's just one thing to watch out for. Finally, one really cool thing you can do with layers is if you want to really get complicated
12:11
with your code is you can actually nest layers inside of each other. So I could have like a utilities layer
12:15
And then inside of this layer, I could say another layer, for example
12:19
And then inside that another layer, I could have my P1 here. So now I essentially have multiple different layers of stuff
12:25
And in order to extend that, I could come in here, I could say like at layer, utilities
12:29
dot another layer, and then inside of here I can, you know, say like dot p2, adding two
12:37
REM, and so on. So if you want to do nested layers, you could do it like this with two layers inside of each
12:41
other or use this dot syntax. Both of those are going to deal with nested layers
12:45
Now I'm guessing for you 99% of the time you're never going to need to deal with nested
12:49
layers because you're probably only going to have a few layers in your code, but it's an important thing to know it exists in case you see it out in the wild, or if you're building
12:55
a framework like bootstrap, having nested layers might really help. Really the important takeaway though is that layers are essentially ways you can group your code
13:02
together to ignore specificity from anything outside of that layer. So everything in one layer is going to only concern itself with the things in that layer
13:09
and everything in another layer only concerns itself with things in that layer, and then you can define the order of the layers to figure out how things override
13:16
So that things like utilities will always override other layers even without having to use important
13:21
This is super useful in my opinion, and I cannot wait for this to be more supported
13:25
The reason I say that is because right now, full support is really only starting to roll out in the brand new browsers from when I posted this video
13:31
That's why as you can see, VScode doesn't even support the layer keyword. But over the next coming months and by the end of this year, I'm assuming, this will be supported
13:38
in pretty much every browser because the newest versions of Chrome, Firefox, Edge, and so
13:42
on already support this feature, but people just haven't updated to those versions quite yet
13:47
So even by the end of next month, this is going to be much more supportive than it already is
13:52
If you enjoyed this video, you're going to love my CSS specificity crash course linked over here
13:57
as well as my selector crash course also linked over here. I also have a full selector cheat sheet which is linked in the description
14:03
It covers every CSS selector you could ever need to know. It's completely free, just click the link down below to get it
14:08
With that said, thank you very much for watching and have a good day