Specificity vs. proximity

Wednesday 8th July

Specificity rules are simple and robust. Despite this, they sometimes ‘break’ in weird and wonderful ways.

A quick CSS teaser

Given the following markup …

<div class="example">
    <div id="outer">
        <div id="inner"></div>
    </div>
</div>

…and this CSS…

#outer { background-color: #eee; }
#inner { width: 6em; height: 6em; padding: 1em; }

#outer div { background-color: #A40000; /* red */ }
#inner     { background-color: #9DB029; /* green */ }

… should the inner div be red or green?

Answer

Sorry, but it looks like you’ve got javascript disabled, so the game’s been spoilt for you ;-)

That was pretty much a rhetorical question (I’m not expecting to catch many people out with that one), but there’s a point behind it, namely: which is more ‘specific’ (in the general meaning of the word, not the CSS definition), the first declaration or the second? I’d argue that the second, addressing the div by its ID, is more specific.

Unfortunately, in this case, to override the existing declaration, one needs to address #inner even more specifically than just via its unique ID:

#outer #inner { background-color: #9DB029; }

Of course, with our above structure, #inner can only exist within #outer, so the context is somewhat redundant, other than the requirement that specificity imposes.

Maybe the issue is that, when it comes to specificity logic, IDs are very different beasts from classes and element names. Whilst class names and element types are ten-a-penny, the ID is unique. Surely, then, a selector targeting an element by its unique identifier should take precedence?

I guess taking context, hierarchy, or proximity into account would complicate the current specificity rules, even it would make them more logical and, in some cases, simplify CSS authoring. I can’t help but think, however, that an ID selector in the ‘most significant position’ (i.e. rightmost) of a selector should be given extra weighting.

What do you think? Should the existing specificity rules be taken as set-in-stone, the best option we have? Or is there room for improvement? Which is preferable: simpler rules, or a more logical, applicable approach? Have you suffered from any other weird nuances when it comes to specificity.


Comments

Leave a comment