Check out a free preview of the full CSS In-Depth, v2 course:
The "Specificity" Lesson is part of the full, CSS In-Depth, v2 course featured in this preview video. Here's what you'd learn in this lesson:

An in-depth look at CSS specificity and the cascade using "SpeciFISHity" illustrations showing the weight of IDs, classes, element and pseudo selectors as well as !important using plankton, fish, and sharks.

Get Unlimited Access Now

Transcript from the "Specificity" Lesson

[00:00:02]
>> Estelle Weyl: So specificity,
>> Estelle Weyl: So in terms of specificity, we've covered a lot of selectors, and they all have a specificity weight. We didn't actually cover the global selector, which is the star, which means match anything and anything and everything, all elements. They will not match all pseudoelements and stuff like that, but it matches everything.

[00:00:30] It has a specificity of 0-0-0. So that sounds like it has no specificity, but it actually has specificity, it matches elements. So it's not that it has no specificity, it's just that the weight is 0. An element has a specificity of 0-0-1. If you have two elements, it's a bit more specific and it would be 0-0-2.

[00:00:54] If you have 12 elements listed in your selector, you've got a problem, but the specificity is 0-0-12. No matter how many element selectors you have, one class selector will overwrite, or will be more specific than no matter how many element selectors you have. So a single class is 0-1-0.

[00:01:22] So whatever that value is in that middle column overwrites the value that's in the right column. So you first compare the column on the left, then the middle, and then the right. So here I have a global selector in front of my class. The global one has a specificity of 0.

[00:01:41] And the myClass has a specificity of 0-1-0, so total, you have 0-1-0. If you have an attribute selector like type=checkbox, that has the same weight as a class selector, so it's 0-1-0 as well. Only-of-type, a structural selector, same specificity, 0-1-0. If you put an element selector with a class or an attribute selector or structural selector, right, you have one class weighted out selector there of 0-1-0.

[00:02:20] And then you have here, you have one element, an <li> here and an <li> there, so 0-1-1. Here, you have two elements, <li> nth-of-type 3n, tilde <li>. So it matches any <li> that is an adjacent sibling that comes after the third. So it'd be the fourth list item, fifth, sixth, seventh, and eighth.

[00:02:42] And it has a specificity of 0-1-2 because we have two <li>s, we have an <li> here and an <li> there. Does that make sense? We start with an <li> and we end with an <li>. Similarly, form input of type email. So it's an input type that has a type attribute with a value of email, that is descendant of a form, right?

[00:03:09] One element, two elements. One element is the input, one element is the form, so that's 0-0-2, plus the attribute selector, which is 0-1-0, so you have 0-1-2. Going down on this page a little bit, which is easier to do in the next slide because this is a pdf.

[00:03:27] So this link right here, you can print it up and put it up on your desk at home. Okay, going down, here I'll skip this one, I'll go to this one. The not, so here we have input that has a type attribute. So that's 0-1-1, and then we have a not and a class.

[00:03:50] The not has no weight whatsoever, it is the parameter that's passed the argument, that is a class, right, so that's 0-1-0. So you have 0-1-0, 0-1-0, and 0-0-1, for a total of 0-2-1.
>> Estelle Weyl: Then here, we have ten classes, attributes and pseudo classes. If you ever do this, find a new job.

[00:04:16]
>> Speaker 2: [LAUGH]
>> Estelle Weyl: But this is what sess or less will sometimes produce. So be careful, right, you don't want to increase your specificity like that, because it makes it really hard to overwrite. And some people will use an id to overwrite this. They should just never produce this in the first place.

[00:04:34] So an id selector is a weight of 1-0-0, and here I use cute plankton, they're the cutest, right? Then the fish, and the shark isn't that cute because the shark isn't that nice. We don't wanna use sharks. We can use sharks if we need to, right, but we wanna avoid them cuz we don't like sharks.

[00:04:56] So basically, try to avoid div-itis and id-itis, because the weight is really high and it's hard to overwrite. So here we have two plankton, two fish and a shark, because it's my id <li>.class a href. So you have one class weight here as an href attribute selector, and one class here, so that's where the middle 0-2-0 comes from.

[00:05:20] You have one element as an a and an <li>, so that's 0-0-2 right there, and then you have one div which is the id selector, so that's 1-2-2. And then here you have div-itis for no reason, you have two id selectors, right? Or almost no reason, it's very rare that you need them, and then the link.

[00:05:41] So you've saying this link that's in my div, that is nested within something that it has div-itis, so this right here is more specific, has more weight than that. Even though this is very specific, right? This is very specific, it's saying, I want a link that has an href attribute that isn't an <li> that has a class of class, that is in this specific div.

[00:06:10] That's very specific, but it has less weight than something saying I have div-itis and I'm gonna use a bunch of ids. Then you have the style, which has more weight than any number of sharks, cuz that's an inline, right? And that is the BP oil tanker. And if we all remember the BP oil tanker that destroyed half of the Gulf of Mexico, we don't like that.

[00:06:33] And even worse than that is important, and that is a nuclear bomb. And important is the nuclear bomb option. So you want to avoid this like the plague. I use it all the time to check out why my CSS isn't working, but I never put it into production.

[00:06:52] I use it in my debugger while I'm in the dev tools. I open it up and I look and I add important, and then I'm like I was targeting a link and this is a button. So I was targeting the wrong element, obviously that's where I went wrong.

[00:07:08] And I find where my mistakes are with important, but I don't put them in. So there's some notes down here. So I already explained that x-0-0 is the div, the number of id selectors. 0-y-0 is the number of class selectors, attribute selectors, and pseudo classes. 0-0-z is the number of type selectors and pseudo elements.

[00:07:30] So element selector, it's actually called a type selector, I was using the wrong terminology. And pseudo elements like first letter, first line, before, and after. And then here, the reason I want to point out the stuff at the bottom is because this is the important stuff. The star, the plus, the greater than, the tilde, and then the space.

[00:07:51] The space that is between that combinator between e space f, that's also a combinator. Those have no value. They increase specificity to make things more specific, but they don't add to the weight. And then the not, and I think I said this enough, but I'll say it for hopefully the last time, the not itself has no value.

[00:08:11] It's the x, it's the argument that increases the specificity. So this basically summarizes all of that and explains how it works.
>> Estelle Weyl: This also, we've already gone over all of this, but it's in writing for later on if you want to use this as a resource. Now, in terms of hacking, I said avoid !important.

[00:08:37] There's a few ways I avoid !important. A lot of people do this, when something has a class of .disabled, make the cursor the default cursor, and make that important, always. Anything that has a class of .disabled, the clicker will never look like it can click on it. p.btn (cursor: pointer;)

[00:09:07]
>> Estelle Weyl: So you have a p that has a class of btn, right, cuz you're an idiot and you wanna make a button out of a paragraph. I'm sorry, I'm really judgmental. So that will never overwrite the previous statement, right? There's no way that thing actually also had the class disabled by accident somehow, that you could have the right cursor.

[00:09:34] So one thing you can do is just do .disabled.disabled.disabled. It's really important to me, but when you need to overwrite it, you can. That's what that's saying, that's giving you a specificity instead of 1-0-0-0-0, it's giving you a specificity of 0-3-0, which is pretty good. You shouldn't be having more than three classes on anything anyway.

[00:09:58] You could put 5, you could put 12. It basically says does the class disabled exist? Yes, okay, so does this other class which says disabled exist? Yes, or does this other class which we have on this list disabled exist, yes so it doesn't have to be on the element three times.

[00:10:14] It only has to be on it once, cuz it basically checks the first one, then the next one and the next one and matches every single time. So that's how that works. Let me go onto one more thing and then answer your question. So that's for classes, but what about divs?

[00:10:26] You have a third party API, they put an id on their thing and they made everything blue, and it just does not match the blue scheme of your website. Uh-oh, right, they put !important on it. Well, you should never put !important if you're doing a third-party widget, cuz you should just,

[00:10:44]
>> Estelle Weyl: Don't buy their stock options. Okay, what you can do is similarly do #TheirWidget#TheirWidget, because you need to overwrite whatever they have. And they've used an id, and you can't go beyond their id selector. How can you do it without !important, right? You could inline style, you could write important, those are your two options.

[00:11:05] If they just did this, right, without the important, right, how can you be more specific than TheirWidget? You just do it twice, right? So it says does it have the id of TheirWidget? Yes, and then it says does it have the ID of TheirWidget? Yes, and so you have 2-0-0.

[00:11:24] Whenever you use this one or this bottom one, disabled.disabled.disabled, in your markup, in your code, always comment out why you're doing it cuz anyone else would think that's a big mistake. And just say adding specificity cuz we will not say what we think of these people who are putting in ids in their third party widgets.

[00:11:49] So hack in case of emergency would be a:not, idDoesNotExist idDoesNotExist id, cuz if you don't know what their ids are, cuz their ids change, right? So this is just saying any a, but it's giving the a a specificity like this is a link element, it's an a element.

[00:12:12] And it's an a with a specificity of 3-0-1, that's how you can give specificity. Don't ever do this unless it's something you can't target, because it's someone else's markup coming from some other server, and you really need to overwrite it. Okay, we're gonna come up on a break soon.

[00:12:34] But before that, I want to cover worst case scenario, how do you overwrite important? This is the worst hack in the world, but it says, color: white !important. Do these look white to you? No, because I have an animation. We'll learn about animations later on, probably tomorrow. It says keyframes color.

[00:13:01] So the name of the animation is color. And at the 100%, make it orange. And then <li> says call this animation called color. And then stop at the 100% mark and leave it there. So if I actually change this to, just to show you that it worked.
>> Estelle Weyl: And this is just in case everyone knows selectors, they don't know this.

[00:13:29] So it's okay, at least someone can learn something during this session.