Grow your CSS skills. Land your dream job.

Specifics on CSS Specificity

Published by Chris Coyier

This article was originally published on August 11, 2008. I am updating it now to fix some inaccuracies in how this concept was presented.

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 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. Another way to juice up the specificity value for your ".favorite" class is to use the !important declaration.

.favorite {
  color: red !important;
  font-weight: bold !important;
}

I once heard it said that !important is like the Jedi mind trick for CSS. Indeed it is, and you can force your will over the styling of elements by using it. But !important imposes that will through drastically increasing the specificity of that particular selectors property.

The !important declaration can be easily misused if misunderstood. It is best used to keep your CSS cleaner, in examples where you know elements with a particular class selector should use a certain set of styling no matter what. Conversely, not used just as a quick crutch to override the styling of something instead of figuring out how the CSS was structured and working by the original author.

One of my classic examples is:

.last {
   margin-right: 0 !important;
}

I often use that in situations where there are multiple floated blocks, for the last block on the right in a row. That ensures the last block doesn't have any right margin which would prevent it from butting snugly against the right edge of its parent. Each of those blocks probably has more specific CSS selectors that apply the right margin to begin with, but !important will break through that and take care of it with one simple/clean class.

Calculating CSS Specificity Value

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 applies vastly different specificity weights to classes and IDs. In fact, an ID has infinitely more specificity value! That is, no amount of classes alone can outweigh an ID.

Let's take a look at how the numbers are actually calculated:

In otherwords:

  • If the element has inline styling, that automatically1 wins (1,0,0,0 points)
  • For each ID value, apply 0,1,0,0 points
  • For each class value (or pseudo-class or attribute selector), apply 0,0,1,0 points
  • For each element reference, apply 0,0,0,1 point

You can generally read the values as if they were just a number, like 1,0,0,0 is "1000", and so clearly wins over a specificity of 0,1,0,0 or "100". The commas are there to remind us that this isn't really a "base 10" system, in that you could technically have a specificity value of like 0,1,13,4 - and that "13" doesn't spill over like a base 10 system would.

Sample calculations



Update: The :not() sort-of-pseudo-class adds no specificity by itself, only what's inside the parens is added to specificity value.



Important Notes

  • The universal selector (*) has no specificity value (0,0,0,0)
  • Pseudo-elements (e.g. :first-line) get 0,0,0,1 unlike their psuedo-class brethren which get 0,0,1,0
  • The pseudo-class :not() adds no specificity by itself, only what's inside it's parentheses.
  • The !important value appended a CSS property value is an automatic win. It overrides even inline styles from the markup. The only way an !important value can be overridden is with another !important rule declared later in the CSS and with equal or great specificity value otherwise. You could think of it as adding 1,0,0,0,0 to the specificity value.

Resources

Comments

  1. Permalink to comment#

    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

  2. mikemc
    Permalink to comment#

    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…

  3. Permalink to comment#

    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).

  4. This makes specifity much easier to understand. Come to think of it, this would make for a nice CSS editor plug-in!

  5. Great explanation, love the visuals.

  6. Permalink to comment#

    Thanks for the post. I’ll care about the calculation beside the order of the code :)

  7. I’ve always understood specificity but I’ve never seen the calculation method, pretty nifty.

  8. Permalink to comment#

    Great explanation. The analogy of the point system makes it really simple to understand.. Thanks

  9. Thanks for this excellent and useful article! This an interesting method.

  10. adam
    Permalink to comment#

    firebug can spare you the “fishing around in your css,” as it nicely displays which selectors are being applied to any element you chose.

  11. 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

  12. I’m used to looking up at the Firebug toolbar if I have the need, but yea, your graphics drive it home. Nice!

  13. Wow, I really do think that this post is one “Aha-Moment” more for many people. Nice illustrations also.

    Greets from Germany

  14. Great stuff for those tricky css tables in design. Thanks

  15. 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.

  16. Permalink to comment#

    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.

  17. Jaik
    Permalink to comment#

    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.

  18. Sean Curtis
    Permalink to comment#

    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.

  19. Permalink to comment#

    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!!

  20. Permalink to comment#

    Great article and the illustrations really help a visual person like me grasp the entire concept. Thanks.

  21. 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?

  22. Permalink to comment#

    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. ;-)

  23. Permalink to comment#

    Being specific always help to understand the code and make sure to keep control over elements.

    Thanks, this is a nice reminder !

  24. Permalink to comment#

    Great article!

    I suggest you to create a printable cheatsheet. That would be useful!

  25. Dathan
    Permalink to comment#

    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.

  26. I’m glad you updated this. I keep seeing CSS Specificity articles (Smashing Mag, NetTuts, even Malarky) getting this wrong when it comes to calculating the specificity values.

    Thanks for updating, I think it’s important to keep information as current and as accurate as possible, because there are still people searching for these answers.

  27. Danger comes with bloat. Careful of those classes and ids! Try planning your site before you code it!

  28. Daniel K

    I always loved Andy Clarke’s Star Wars figure diagram for this.

  29. I’m w/ Scott Corgan.

    I try to use as little classes and id’s as possible. If I have to use them, I name them very generically so they can be used universally.

    Another rule of thumb is if my CSS has more than 1 class or id before the actual element then I’m probably doing something wrong.

  30. Nice use of graphics to illustrate your point.

  31. Hi Chris! Great post. I was wondering if you could eventually post all your custom class CSS-Tricks in one neat post/page. For example you mentioned in this post your .last {} class trick which you made when you boarder/float issues. I think it could be usefully to put those items in the CSS reset file and you could use them over and over.

  32. Well laid out. Thanks!

  33. Hello there, I would like to introduce a simple way to avoid that .last margin-right: 0 !important trick you exemplify above.

    If you could read in brazilian portuguese, fine, if don’t, please use some online translator (I did it using Google Translator for you, just click here http://bit.ly/baZpJ6) and take a look at this article of mine http://edsonjunior.com/lista-de-itens-horizontal/

    By the way, nice article. Just add into my delicious! :)

  34. One good reminder is to avoid being more specific than you need, sometimes it can help performance and also makes maintenance/re-use easier. You don’t need the “ul” on “ul#summer-drinks” since you can only have one ID per page.. having less and more efficient selectors make your page render faster.

    Another thing is to always put elements (e.g. “p, a, h1″) and generic classes (e.g. “last”) before the other rules, it’s easier to understand what will be overwritten..

  35. Well done, dude! really nice drawings *g*

  36. This is one of my favorite articles about CSS specificity. I never really was able to really understand what this was all about even when I was going to school The teachers I had didn’t really explain it all that well. It is amazing that CSS really is all that powerful. I don’t even know anything about CSS5 so I have a long ways to go.

  37. Interesting way to calculate that. Many times i ended putting “!important” instead of try to find out what was wrong.

  38. Nice of you to update this. On the web these days, all I find is older, incorrect information. You are one of the short list of good websites on the net.

  39. Specificity is one of the most confusing aspects of CSS. Your article is the best I’ve seen at explaining it, an excellent job.

    I’m concerned about people finding this article. When I first stumbled on to the issue several years ago, I had no idea it was called “specificity.” I was simply trying to find out why styles attached to an id were overriding styles defined by class on an element contained within the id’ed element!

    It would be very interesting to learn what people searched for when they were trying to get past this and then make sure the article was responsive to such searches.

  40. I don’t like using the universal selector *, sometimes i lose the control of it and maybe other designers couldn’t understand my CSS code.

  41. Permalink to comment#

    Thanks for this article!

    You reminded me that the universal selector has no specificity :)

    I also use a different system when I want to share a specificity whit another developer.

  42. Crazyturkish19
    Permalink to comment#

    I found your “!important” on specificity explanation little confusing. For example:

    <style>
        .foo{ color:red!important;}
        a {color:green;}
    </style>
    
    <p class="foo">
           <a href="#">Foo</a> Bar
    </p>
    

    The color of “Foo” text in “a” will be green but most people might think it is red.

    • Dylan Archer
      Permalink to comment#

      !important applies to the element it is assigned to, not child elements. I believe <a> is considered a child of <p> in this case. Any text within the parent element would be red regardless of what styles were applied to the universal p selecter; However <a> would retain it’s specified styles.

  43. Using the Bootstrap boilerplate from Initializr.com, there is a built-in style, which appears to have a specificity of 0,0,1,0:
    .col-lg-4 {
    width: 33.33333333333333%;
    }

    I wanted to give it rounded corners with a border (no problem) and give it a little room between columns so the borders don’t touch. I created this code, which to me seems to have a specificity of 0,0,2,0:
    .col-lg-4.rounded {
    margin-right:0.5%;
    width: 32.83333333333333;
    }

    According to Firebug, both selectors are considered, but the non-.rounded loses to the regular one. So, I tried creating the inverse, which to me seems to also have a specificity of 0,0,2,0:
    .col-lg-4:not(.rounded) {
    width: 33.33333333333333%;
    }

    Sure enough, it beats out the plain one, apparently because it has more specificity.
    I also tried changing around the order of the selectors, inline vs. included, and the order the classes are listed (.rounded.col-lg-4), and nothing made a difference. I did my testing in Chrome.

    So it makes me wonder why two classes on the same element along with a selector that targets both, not have higher specificity than a selector targeting only one? Or maybe my math is just wrong?

    • I found the issue. There is a @media selector above that covered the style I was trying to override. Therefore, I suppose that means that @media has a very high value, though I’m not exactly sure where it would fall into this hierarchy. Perhaps that information could be added to this article?

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".