Specifics on CSS Specificity
* 8/11/2008 — 45 Comments *
I’ve never specifically covered this subject before. (rimshot!)
The best way to explain it is to start with an example of where specificity gets confusing and perhaps doesn’t behave like you would expect. Then we’ll take a closer look at how to calculate the actual specificity value to determine which selector takes precedence.
Here is a simple unordered list:
<ul id="summer-drinks">
<li>Whiskey and Ginger Ale</li>
<li>Wheat Beer</li>
<li>Mint Julip</li>
</ul>
Now you want to designate one of these your favorite drink and change its styling a bit. You need a hook for this so you apply it via a class name on the list element.
<ul id="summer-drinks">
<li class="favorite">Whiskey and Ginger Ale</li>
<li>Wheat Beer</li>
<li>Mint Julip</li>
</ul>
Now you pop open your CSS and do your styling for your new class:
.favorite {
color: red;
font-weight: bold;
}
Then you take a look at your work, but alas, it didn’t work! The text of your favorite drink didn’t turn red or go bold! Something fishy is at work here.
Poking around more in the CSS, you find this:
ul#summer-drinks li {
font-weight: normal;
font-size: 12px;
color: black;
}
There is your trouble right there. Two different CSS selectors are telling that text what color and font-weight to be. There is only one statement for font-size, so clearly that one will take effect. These aren’t “conflicts” per-say, but the browser does need to decide which one of these statements to honor. It does so by following a standard set of specificity rules.
I think this confuses some beginners because they haven’t quite gotten this sorted out yet. They might think because the .favorite statement is “further down in the CSS” or because the class=”favorite” is “closer to the actual text” in the HTML that will be the one that “wins”.
In fact, the order of selectors in your CSS does play a role and the “further down” one does in fact win when the specificity values are exactly the same. For example:
.favorite {
color: red;
}
.favorite {
color: black;
}
The color will be black… but I digress.
The point here is you want to be as specific as it makes sense to be every chance you get. Even with the simple example presented above, it will become obvious to you eventually that simply using a class name to target that “favorite drink” isn’t going to cut it, or won’t be very safe even if it did work. It would have been much smart to use this:
ul#summer-drinks li.favorite {
color: red;
font-weight: bold;
}
That is what I’m calling “being as specific as it makes sense to be”. You could actually be way more specific and use something like this:
html body div#pagewrap ul#summer-drinks li.favorite {
color: red;
font-weight: bold;
}
But that is over the top. It makes your CSS harder to read and yields no real benefits.
Calculating CSS Specificity Value
But just why is that our first attempt at changing the color and font-weight failed? As we learned, it was because simply using the class name by itself had a lower specificity value and was trumped by the other selector which targeted the unordered list with the ID value. The important words in that sentence were class and ID. CSS doesn’t care what try to do with classes and IDs, but it does apply vastly different specificity weights to them. In fact, an ID holds 10x greater importance than a class.
Let’s take a look at how the numbers are actually calculated:

In otherwords:
- If the element has inline styling, that automatically wins (1000 points)
- For each ID value, apply 100 points
- For each class value (or pseudo-class or attribute selector), apply 10 points
- For each element reference, apply 1 point
Sample calculations





Important Note
The above examples are really close to how the CSS specificity value is calculated but with one important exception. The numbers aren’t really “added together” in BASE-10 like that, they are really appended together in kind of a BASE-INFINITE kind of way. So 231 is really like 2,3,1. The important distinction here, a Jonathan Snook points out below, is that if any of these numbers goes over 9, they don’t spill over into the next digit like they would in BASE-10. So a selector could have the value 2,11,1, it wouldn’t be calculated as 311. Thanks to Eric Meyer for jumping on this distinction below. Eric also has a page on specificity as well.
Resources
- Smashing Magazine has a pretty comprehensive article on CSS Specificity
- W3 specs
- IE Quirks (try viewing this page in Fx and then IE)
- Fuzzy Specificity Hack: IE (even beta 8!) and older Opera browsers have a bug honoring the correct selector under specific circumstances.





Hello!
Thanks for this article! I’ve gotten into a real habit of using very specific styles recently. Also I really like how you layout your CSS file from looking at some of the screencasts you have! That has helped a lot and now my CSS files are so much easier to read.
Keep up the good work on the site!
ChaZ
I’m one of those “confused beginners” referenced in the article. :) This helps a lot. This will definitely be bookmarked and referred to often.
Thx…
I would also recommend checking out and test the CSS Specificity Calculator. Just paste in your CSS and it’ll calculate the specificity for you. It really comes in handy if you’re working on large CSS files (instead of multiple smaller ones).
This makes specifity much easier to understand. Come to think of it, this would make for a nice CSS editor plug-in!
Great explanation, love the visuals.
Thanks for the post. I’ll care about the calculation beside the order of the code :)
I’ve always understood specificity but I’ve never seen the calculation method, pretty nifty.
Great explanation. The analogy of the point system makes it really simple to understand.. Thanks
Thanks for this excellent and useful article! This an interesting method.
A very good article that explains the “scoring” system of specificity in CSS well, but there is a glaring error in your example. If you actually try the example you’ll notice that it does redden and embolden the first list item.
Since the class is on the li, it overrides the style that is inherited from the ul#summer-drinks selector. Either you’ve misunderstood specificity and inheritance somewhat yourself, or more likely you’ve made an error and that selector should be ul#summer-drinks li.
@Jaik: Yep, you are right, that selector should have been “ul#summer-drinks li” in the article. Even thought the specificity value is technically higher for the “ul#summer-drinks” selector alone, it is targeting a different element (the list not the list item), so the class would win.
firebug can spare you the “fishing around in your css,” as it nicely displays which selectors are being applied to any element you chose.
Very nicely written.
Thank u.
I rarely run into those troubles but when i do; first thing that hits my mind is firebug.
But whats new to me here is the “Calculating CSS Specificity Value” i read about it in some book but didnt get through to me. now its so simple to remember.
thx again.
Cheers
I’m used to looking up at the Firebug toolbar if I have the need, but yea, your graphics drive it home. Nice!
Wow, I really do think that this post is one “Aha-Moment” more for many people. Nice illustrations also.
Greets from Germany
Just to clarify that the specificity calculator isn’t entirely accurate. For example, if you had an element with 11 classes applied to it, it would not outrank an element with a single ID selector.
for example,
.a .b .c .d .e .f .g .h .i .j a.k { color:red; }
#myel {color:blue;}
<span class=”a b c d e f g h i j k” id=”myel”>would still be blue.</span>
The chances of this are slim but important to note.
Great stuff for those tricky css tables in design. Thanks
Just to add on to Jonathan Snook’s comment:
The calculation is not based on “addition” of the values. The specificity calculation is instead based on the left most value being the highest. If two competing selectors have matching values for a given identification unit, then comparison continues towards the left next order until a larger value is found.
I’ve highlighted this bit in a chart in my article on CSS specificity.
Something I always wanted to know in CSS is whether is possible to create shortcuts to colours.
At the moment in my websites if I need to change the color code from a font, I need to check all the classes that have the color applied to it.
If I had, however, I “shortcut” named “myCustomYellowColor” that would have a custom color code, I would be able to change it all at once in a single line.
pablo, you can’t create constants or variables in CSS, but it’s something I’ve yearned for somewhat myself. The best way I found is to put the common colours in one place. For example:
h1 { font-size:1.6em; }h2 { font-size:1.4em; }
a { text-decoration:none; }
h1, h2, a { color:#ff9900; }
Another option if you’re after something a bit more complex is Shaun Inman’s CSS Cacheer.
Pablo – CSS Variables are on their way. They’re available in the most recent builds of Webkit (Safari) but won’t be mainstream for quite a while yet.
If you split your styles up into typography and structure/layout it can make it a lot easier to change – however depending on the size of your stylesheet it can make things a bit harder to find – eg. if you’re looking for all styles of a particular element/selector you have to reference multiple locations instead of just the combined typo/structure one.
Jonathan is entirely correct, and the article is deeply misleading on that particular point. Specificity is not base-10. It’s not base-anything-familiar: in fact, specificity values have an infinite base. Really. So you don’t “add points together, at least not in the manner which just about anyone reading this article would assume.
That’s why a separated notation (commas are most common) is preferred when writing specificity values. See http://meyerweb.com/eric/css/link-specificity.html for an example, or the CSS2.1 specification itself.
Thanks to Jonathan and Eric for popping in to set the record straight. Indeed, specificity is not calculated in base-10. However, as Jonathan pointed out, unless any particular digit goes over 9, this is not a problem. And I feel like your code has some deeper problems if you have more than more than 9 elements, classes, or ID’s on any particular CSS selector =)
I’m gonna pop back into the original article though and add a section explaining this though, in case anyone does reference this article and is misled.
Andy Clarke’s Specificity Wars post from a couple of years back is the way I understand specificity.
It doesn’t matter how many storm troopers you’ve got, they’ll never beat a Darth Vader!
I thought I was pretty pro with specificity, but I never knew the different types of selectors had actual numeric values assigned to them, great article!!
Great article and the illustrations really help a visual person like me grasp the entire concept. Thanks.
Thank you Chris for great article. I also like your visual explanation – BTW what software do you use for your visual elements in your articles?
Wow, Eric Meyer was a little harsh… unlike Snook’s milder and more constructive response.
I — for one — fell in love with your base-10 approximation that so cleverly lends itself to intuitive graphical examples. I often explain specificity to co-workers, but never have my words been as clear as when (this morning) I was armed with a printed copy of your article and those cute, base-10 score bubbles. Seriously fine work!
BUT… it feels like something important is missing. ;-)
Being specific always help to understand the code and make sure to keep control over elements.
Thanks, this is a nice reminder !
Great article!
I suggest you to create a printable cheatsheet. That would be useful!
Great article on CSS specificity! An explanation isn’t even necessary, the pics suffice. But Chris, in light of Eric Meyer’s correction, why don’t you fix your pics? Remove the pluses and add the commas.
I think :first-letter is a pseudo-element worth 1 point and not a pseudo-class worth 10 points. Can anyone confirm this?
That’s correct, Alex. Also, for obscure technical reasons, pseudo-elements are ignored in specificity calculations in CSS2 (http://www.w3.org/TR/CSS2/cascade.html#specificity) but get one point in CSS2.1 (http://www.w3.org/TR/CSS21/cascade.html#specificity). Which occurs depends on which set of rules your browser implemented, of course.