The importance of being !important
There are plenty of good articles describing how CSS specificity is calculated for normal rule-sets, but the !important modifier is often ignored or overlooked. However, with a little manipulation, !important can simply be treated as one more factor in the specificity calculation.
To see how this works, consider this rule-set:
p.error {
height: 23px;
color: red !important;
background: black !important;
border: 1px solid red;
white-space: pre;
}
Separating the !important properties from the rest gives:
p.error {
color: red !important;
background: black !important;
}
p.error {
height: 23px;
border: 1px solid red;
white-space: pre;
}
Both rule-sets have the same selector, and therefore the same specificity; but I think it helps to consider the !important rule-set as having a higher specificity. We can do this by treating !important as part of the selector.
Faux Selectors
Let’s move the !important modifier outside the brackets:
p.error !important {
color: red;
background: black;
}
p.error {
height: 23px;
border: 1px solid red;
white-space: pre;
}
Note: although ”p.error !important” isn’t a valid selector, I hope the intent is clear.
Using the CSS 2.1 definition of specificity, an inline-style would have the highest specificity (1,0,0,0), while p.error has a specificity of 0,0,1,1 (in order: 0 for not being inline, 0 IDs, 1 class, 1 element name.) But, !important rules override inline-styles, and !important inline-styles override everything; so wouldn’t it make sense to give !important rulesets a higher specificity?
Here’s the instruction used to calculate the first number in the specificity of a selector:
count 1 if the declaration is from is a ‘style’ attribute rather than a rule with a selector, 0 otherwise (= a) (In HTML, values of an element’s “style” attribute are style sheet rules. These rules have no selectors, so a=1, b=0, c=0, and d=0.)
I suggest modifying that to: count 1 if the declaration is from a ‘style’ attribute, 0 otherwise. Add 2 if it’s !important (= a).
Effectively, all we do for !important rulesets is to add 2,0,0,0 to the normal specificity.
Summary
By considering !important properties as belonging to a ruleset of their own, we can list four levels of specificity. In decreasing order of importance, these are:
!importantinline-styles (3,0,0,0)!importantrulesets (2,b,c,d)- standard inline-styles (
1,0,0,0) - standard rulesets (
0,b,c,d)
As you can see, !important rulesets still compete over the b, c and d of specificity, and that’s where the difficulties usually lie.