The way that CSS's specificity (how browsers choose which CSS rules to apply) works can be a little baffling, even to old hands. I was writing rules for this site and ran into a problem where one style was overriding another where, I thought, it really shouldn't.
The problem was that I'd forgotten an important aspect of the way that selector specificity is worked out.
Consider these two selectors and a snippet of HTML:
div.special ul.extraSpecial li.reallySpecial a:link { color: blue; }
#billy a:link { color: red; }
<div id="billy" class="special">
<ul class="extraSpecial">
<li class="reallySpecial"><a href="test">List item</a></li>
</ul>
</div>
Which one is going to match the <li> in that HTML?
Last week, I would've said the first rule. But I'd have been wrong. Oh so very wrong.
According to the spec, specificity is worked out by calculating 4 values and then concatenating them, which is enough like adding up to confuse. The 4 values are:
style attribute (i.e. inline) or not [1 or 0]#billys there are) [add them up].special or [href="index.html"] [add them up]Note that there's nothing there about what order the various ids and classes and what have you are in, you just count 'em. Nice and simple.
So, if we go back to our first example and do the sums then we get the following results:
div.special ul.extraSpecial li.reallySpecial a:link { color: blue; } gives us:
#billy a:link
:link counts too): 2At first sight it looks like rule 1 scores 8 and rule 2, just 3. But we're not adding the totals, we're concatenating them, so rule 1 = 0035 = 35, but rule 2 = 0102 = 102, which is miles more specific...
In conclusion, watch where you put those ids...