CSS Specificity Didn’t Work the Way I Thought
While preparing for interviews I decided I would really, really wrap my head around CSS specificity today. So I read this article on Smashing Magazine and thought “Great! I get it now.” Or so I thought.
It seemed simple enough. A selector gets 1000 points if it’s inline styled, it gets 100 specificity points for every id selector, 10 for every class, attribute, or pseudo-class selector, and 1 for every element or pseudo-element. So I created a little test:
Based on this formula, the
.test selector should have a specificity of 10, and the
html body main article section form div figcaption div p span em selector (think I set a record there!) should have a specificity of 12, and the text TESTING 123 should render in red.
But here’s what I got:
Some helpful Stack Overflow users explained it a little better — essentially, yes, we do add the numbers together. But it’s not in base 10. In fact, specificity is calculated based on an arbitrarily large number base. In English, that means I could have 100000 element selectors and one class selector, and it would still be green in this example. I can only really compare numbers of selectors in a specific category — so for example 3 element selectors beats 2, and one class + one pseudo class beats one class selector.
Props to @dippas on StackOverflow for this image showing it visually:
And incidentally, this is why ID selectors are frowned upon, because I can have one ID selector, and TREE(3) element selectors (assuming your computer didn’t collapse into a black hole), and the ID selector would still win.
EDIT: I have since learned the previous sentence is false. The actual number of selectors needed to win, depending on browser, is between 256 and 2¹⁶ = 65536. But I recommend clicking the link to look at TREE(3) anyway if you’re bored and want to have your mind blown ;-)
And then you get frustrated and slap
!important on everything and then the whole stylesheet becomes a mess.
Learn something new every day! :)