Intermediate HTML & CSS

CSS Specificity Overview

Jen Kramer

Jen Kramer

Intermediate HTML & CSS

Check out a free preview of the full Intermediate HTML & CSS course

The "CSS Specificity Overview" Lesson is part of the full, Intermediate HTML & CSS course featured in this preview video. Here's what you'd learn in this lesson:

Jen explains how specificity is calculated. The formula counts the number of IDs, classes, and type selectors. A rule with a higher specificity will override less specific rules.


Transcript from the "CSS Specificity Overview" Lesson

>> There earlier we had a look in depth at inheritance. The next thing I wanna talk about is specificity. And this is a topic that you may know something about already but we're going to drill into this into great detail and take a look at how specificity will work inside of our CSS.

So let's start with our definition from MDN. Specificity is the algorithm used by browsers to determine the CSS declaration that is the most relevant to an element, which in turn, determines the property value to apply the element. So that is what we are looking at today and I know that a lot of you are familiar with this.

Because as you are working away you do things like add an ID to your selector in order to make it more specific so that hopefully it will apply to whatever it is you're trying to style. So that is the concept that we're talking about here. In day one of boot camp, maybe possibly day two, you were taught this, ID's always be classes, always be type selectors, also those elements inside of your CSS, that this is always true.

And as we just showed, this is true until you're gonna factor in the cascade and inheritance. So if we look at specificity in a vacuum and pretend that inheritance and the cascade don't exist, this is in fact true. But, of course, we can interfere with this by adding in inheritance or lack of inheritance, depending on how we've coded things, and by factoring in what's going on with the cascade.

So right now for the purposes of learning specificity, we're gonna focus on this in a vacuum and pretend that inheritance and the cascade do not work in this world at the moment. While we are also discussing specificity to sort of neutralize the cascade, we have to assume that all of our styles are gonna originate from the same style sheet or source.

So we are going to forget about the fact that we have all of these style sheets coming in from all of the different external style sheets, all of the embedded style sheets, inline styles. We're gonna pretend none of that exists just for the purposes of understanding specificity because that is part of the cascade.

So when we think about how specific something is, there's actually a little bit of math that's done, it's really easy, it's actually counting. And what we're going to do is for our given selector we are going to analyze it. We are going to count how many of each type of selector, components of that selector, are contributed to it overall.

So how many ID's do we have, we're going to give that a number. We're going to look at how many classes that we have, in this case, classes as you know and love them. But also lumped in here are pseudo-classes, those are generally things that start with the single colon.

There are a lot of pseudo-classes these days but some of the classic choices are, link, visited, active, hover, focus. We saw a bunch of them, the nth child, nth of type, those are pseudo-classes. And then we have attribute selectors. So all of the attribute selectors, regardless of type, whether they are exact matches or they're some of the substring variants, all of those attribute selectors are included as part of that.

And then finally, we have our type selectors. Which is some kind of element, right, p-body, for example, and all of those pseudo-elements. Generally speaking at this point in time, pseudo-elements start with a double colon, double colon after, double colon before. But in previous versions of CSS prior to CSS3, we had pseudo-elements but they have only single colon to them.

So sometimes you will see, for example, before written with a single colon instead of a double colon. That is the reason why before is one of the older pseudo-elements and some people will still write it with a single colon. So watch for that, it can trip you up in determining the specificity of a given selector.

So those are the big rules when it comes to figuring out specificity. Then we have all the exceptions to the rules. So here's the way the exceptions work. First of all, what has no specificity to it at all. When you see it in a selector, we don't count any of them, these.

That would be the universal selector, the star and the where pseudo-class. Where itself counts for nothing, any selector inside of the where parenthesis counts for nothing, so it has no specificity whatsoever. We don't need to count in our specificity calculations the parent child selector or the adjacent sibling selector or the general sibling selector.

We don't need to count those at all, they may show up in a declaration, we can safely ignore them. Two big exceptions when you are thinking about specificity are the not and is pseudo-classes. With these, we don't count them as pseudo-classes, so we don't count them as not with its number and is as a number.

But inside of the parenthesis we do count some portion of those selectors. And in the case of is we would take the one with the highest specificity and the same is true for not. So whichever selector inside of the parenthesis has the highest specificity, that is the one that counts.

So let's see how this works. We're gonna calculate that specificity by counting and then we're going to generate basically what amounts to a 3-digit array. It's not a number like 100 or 120, it is an array of one dash one dash zero, so think of it that way.

Estelle Weyl has done a great job of explaining this specificity work through her CSS specificity page which you can get to by going to It will walk you through a lot of these calculations. At the end she throws in also inline styling and bang important, which we're gonna talk about a little bit later.

It does need a little bit of an update now with these new pseudo-classes for is and where, in particular, need to be reflected on this and she says that's coming. But that is a great resource to take a look at, to print out, to put by your desk if you need a reference to remember exactly how this works.

So let's do a few of these now. I'm gonna give you a selector, I've given you the cheat sheet underneath and I want you to take a look at that selector and see if you can calculate its specificity. So, for example, here is ul li a. Those are three type selectors, so we have no ID's, no classes, three types selectors, our number is 0-0-3 Go onto another one, we have div#anchor, one id, no classes, one type, so our number is 1-0-1.

A.bgcolor:hover, so we have a with a class of background color in the hover state. So here we have no ID's, we have a class of bgcolor, we have a pseudo-class of hover and we have an a selector, just type selector, so this would be 0-2-1. We get more complicated, you might have something like this, ul li:nth-child (even) a:any-link.

Count them up again, we have no IDs. We have two pseudo-classes, any-link and nth-child. We have three HTML elements in that type selectors, 0-2-3. Here's survey li + li : : first-letter. So first-letter is a pseudo-element, li of course is a type selector survey is an ID. So that would be 1-0-3.

Ul * link, we're going to count those up, link is a pseudo-class, active is a class, so that is 2. We have no IDs, we have ul and a those are type selectors. And then remember the universal selector counts for nothing, so our number is 0-2-2. Here's article:not(#beginning) h4.small.

So beginning is an ID it's inside of the not pseudo-class. We count beginning as an ID, but we don't count not. So we have one ID, one class, two HTML elements, so we have 1-1-2. What about where? So here with where we have it inside of the parenthesis, we have a type selector, we have a class and we have an ID.

Outside of it we have a type selector and a pseudo-element. So how do we count this? It is actually going to be 0-0-2 remember with where, it counts for nothing. Everything inside of the parenthesis counts for nothing, where itself counts for nothing. It is 0-0-2, just the 2 for the li and the marker.

What about the same selector using is instead, this is going to be different. We count the highest specificity inside of the is parenthesis. So here we're going to count the ID of important, but not the article, not the warning. So our number this time is 1-0-2. All right, so with that in mind as to how we calculate our specificities, let's go take a look at some of this inside of code.

Learn Straight from the Experts Who Shape the Modern Web

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