css specificity/the battle for dominance
css is built around the struggle for dominance. The whole concept of css is constructed around cascading, better known to most people as the waterfall principle. While many people understand this principle, the exact details of the way css is applied in real life are usually a bit fuzzy. So no better time than the present to freshen up on css and the specificity of css selectors.
css specificity and exactness
css specificity is a misleading concept. If we look at the definition of specificity, the following is probably the most common interpretation:
quote The exactness with which a vocabulary term covers a concept. unquote
Although it does cover the way css specificity is implemented, it is easy to misunderstand or misinterpret this definition. The "exactness" of css is a little different than you might expect at first glance.
css has more than one way to target a single html element. It can be done through ids, classes, pseudo-classes, the html elements themselves, through css selectors or even inline. All these ways carry a different weight of importance. So it makes a great difference whether you target a div through its class instead of its id. This weight is crucial when the "exactness" of a css rule if computed.
calculating specificity
Each selector carries a weight that represents its specificity. The sum of all these values is the computed weight for a selector, based on all elements within the selector. A little overview of the possible weights:
- 1,0,0,0 : inline styles
- 0,1,0,0 : ids
- 0,0,1,0 : classes, pseudo-classes and attributes
- 0,0,0,1 : elements and pseudo-elements
- 0,0,0,0 : the * (universal selector)
Completing this list are inherited properties and combinator, which carry no weight at all. This is different from the universal selector, which will still overwrite inherited properties.
It is possible that certain elements are targeted by more than one selector carrying the same weight. In this case, the selector appearing last in the source will take preference. An important rule which the whole concept of conditional comments is based on and which should be abused when dealing with IE6 faulty selector implementation.
9+1 is not 10
Something that got me confused at first is the fact that these calculations are not made in base-10. For example, you cannot get 11 classes to overwrite 1 id. Hence the representation of the values with "," which helps to clear up some possible confusion. All specificities are simply added within their respective weight category and the results is then compared to other selectors. A few simple examples:
h1 (weight: 0,0,0,1 )
* h1 (weight: 0,0,0,1 )
.class #id #id2 p (weight: 0,2,1,1 )
#id2 #id p .class (weight: 0,2,1,1 )
.class.class2>*~p (weight: 0,0,2,1 )
important addendum
h1 {color:#c0c0c0 !important;}
The !important declaration is a nasty little back door in the css specificity rules. By declaring something !important you fix that value as unchangeable. No other rules can change this property, no matter what their specificity is. Use this statement with caution, and don't abuse it when you are too lazy to find out which rule is holding your declaration back. !important should only be used within user style sheets or when delivering a piece of code that cannot be overruled by others. Apart from that, avoid it.
past articles revisited
In the end, css specificity is not all that difficult although it can be somewhat confusing. It plays a small role in the choice of class versus id as a targeted id can never be overruled by a string of classes in css. It plays another role in the ordering of css rules in combination with the nasty IE6 double class bug, as this bug has a huge effect on the specificity of a css rule (since classes are ignored and are not computed in the final value). Important things to consider when writing css.
I hope this brought some light in the darkness for some of you. It's all quite straight-forward but unless you're aware of all the details css specificity can be quite surprising.

One point on your important addendum. Yes, it overrides all other CSS, unless those rules also have an “
!important”on them. In the example:span.aaywill have precedence over.beebecause it has higher specificity and an “!important”Important should be avoided at all costs except for quick testing (but remember to remove it later!). If you need to keep the style and you need to override some other style, it's nearly always possible to increase the specificity of the rule you're creating without resorting to important in the end.
And putting important on an inline style is an absolute no-no! That makes it impossible for an end user or agent to override the styles for accessibility or other purposes.
Good additions John, thanks for the heads up :)
I thought I understand this but obviously have it wrong - I wanted to color rows in a table differently this is how the code was set up
td{ background-color:#CCC; } .altRow{ background-color:#fff; } I applied the class to the <tr class="altRow"> but the td background color overrules I know what I have to do to fix it
tr.altRow td{.... but I don't understand why shouldn't the class overide the td? Thanks Vix
I am having the same problem Vic. I actually was trying for six separate rows, each with a different color.
I used: td{ background-color:#EEE; } .Row{ background-color:#CCC; }
My background is taking predominant as well. Any help would be appreciated, novice here.
Still i m bit confused about css specificity. will you please guide me in depth.
* required fields