Posts Tagged standards
CSS Specificity is !important
Posted by Martin in CSS, Web development on May 29th, 2009
In CSS there is a way to overrule the CSS specificity. By adding the rule !important to a CSS declaration you make sure your declaration will take precedence over a normal declaration. This functionality was built into CSS so that users can overwrite an author’s declaration (so that people with special requirements, e.g. need for larger fonts etc., can take control over the presentation).
Nowadays this technique is widely abused by people that don’t understand CSS specificity (or don’t bother to learn). And it is a problem, because the only thing that can overrule an !important rule – is another !important rule …
Lately I have encountered some unnecessary !important rules in different projects at work as well as in plug-ins and products on the web. So I’m going to shed some light on the subject.
You can apply your CSS declarations in many different ways. You can do it by addressing all elements of one kind, all elements with a specific class, a specific element with its ID, all elements with a specific attribute and value, inline styles etc. There are four things that count when a rule’s specificity is calculated:
- Is it an inline style (declared on the element with the style attribute)
- The number of IDs in the selector (#id)
- The number of other attributes and pseudo-classes in the selector (.class, [type=text] and :hover)
- The number of element names and pseudo-elements in the selector (div and :first-child)
Plus the “joker” and an exclusion question:
- Is the rule declared as !important
- The row count where the selector is declared
First the rule’s specificity is calculated into an array and then compared to other rules starting the comparison with index 0 – the higher value, the stronger selector. If one of the two wins at one of the indexes, we have a winner and we exit comparison (so basically, the specificity value [1,0,0,0] would win over [0,1,0,0] and [0,1,0,1] would win over [0,0,5,4]).
If they are all the same value on each index (lest say [0,0,1,0]), the exclusion question kicks in – the row number where the rule is declared. The same thing here, the higher row number, the stronger selector.
If one of the declarations contains an !important rule it wins over all non-!important rules (including inline styles), but then the comparison start all over for all !important rules. So if you would have all declarations with !important, you would end up with the same result as if all where without (except for all inline styles).
Finally, some examples (in order of strength – strongest at the top) with the specificity values to the right:
<a id="x1" style="color: red;">Green text</a> <!-- [1,0,0,0] -->
#x1 { color: green important!; } /* [1,0,0,0] */
#foot #address { … } /* [0,2,0,0] */
#foot #address a.email:hover { … } /* [0,2,2,1] */
#foot { … } /* [0,1,0,0] */
.content .left { … } /* [0,0,2,0] */
a:hover { … } /* [0,0,1,1] */
.content { … } /* [0,0,1,0] */
ul li a { … } /* [0,0,0,3] */
li:first-child { … } /* [0,0,0,2] */
p { … } /* [0,0,0,1] */
To easy get an overview over what rule wins, a tip is to use Firebug for Firefox. Right-click an element and pick Inspect Element. In the Firebug pane, select the HTML tab to the left and the Style tab to the right. You will then see in the all the “looser rules” displayed in the list as lined-through.
I hope this helps you the next time you sit there pulling your heir trying to figure out why the f**k the link is still blue.
More in-depth information can be found at W3C’s documentation on “The Cascade”.