Cascading order in CSS
Sunday, December 14th, 2008I’ve been working with CSS for years now, and I’ve been following two simple rules about overriding styling rules. I like to call them the position rule and the origin rule.
- The position rule
If two or more rules with the same name exist, the latter wins and overrides the others. - The origin rule
In line style rules overrides style rules in the header, and styles in the header overrides external style sheets
Example
Just following these two rules works in most cases, but can give you some interesting bugs. A bit deeper understanding of a third rule will help with these bugs and how to avoid them.
The third rule you need to be aware of is the specificity rule. This dictates that the more specific a rule is, the more weight it has, and thus it’s more important. Even if a rule is after that one, the latter will be ignored and the more specific will be used. It is pretty straight forward, and the w3 cascading rules does a good job of explaining the idea behind it:
A selector’s specificity is calculated as follows:
- count the number of ID attributes in the selector (= a)
- count the number of other attributes and pseudo-classes in the selector (= b)
- count the number of element names in the selector (= c)
- ignore pseudo-elements.
Concatenating the three numbers a-b-c (in a number system with a large base) gives the specificity.
Some examples:
* {} /* a=0 b=0 c=0 -> specificity = 0 */ LI {} /* a=0 b=0 c=1 -> specificity = 1 */ UL LI {} /* a=0 b=0 c=2 -> specificity = 2 */ UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */ H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificity = 11 */ UL OL LI.red {} /* a=0 b=1 c=3 -> specificity = 13 */ LI.red.level {} /* a=0 b=2 c=1 -> specificity = 21 */ #x34y {} /* a=1 b=0 c=0 -> specificity = 100 */
Order doesn’t matter, and it only counts for one group at the time. IE: “UL LI, LI #rawr {}” gives us a specificity of 2 for first group and 101 for the second group.
The only other rule that over rides everything else is the ‘!important’ rule (buggy in IE6). Though, you can read that in the w3 cascading rule 6.4.2.