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:
!important
inline-styles (3,0,0,0
)!important
rulesets (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.