css specificity pt2/lacking proximity
In last week's article on fuzzy css specificity I presented a case that illustrated the difference between regular specificity and css specificity. While it's interesting to review these cases, it's even better to get to the very core of them. This article will do just that.
abstract case: where am I
Real-world case: I'm standing on this Earth, in Belgium, in Antwerp, in Central Park
Translated to css: .planet#Earth .country#Belgium .city#Antwerp .park#Central me
Before starting, let's consider this little abstraction of the issue we're dealing with. Throughout the article I'm going to use the above case to illustrate the difference between regular specificity and css specificity. It's a real world case easily translated to css, describing my current position on this very planet. I've used classes for generic concepts and ids for unique instances of these concepts.
specificity
Specificity is about eliminating options. Making a description more specific will eliminate the chance of error and misunderstanding. It's like a game of darts, where you try to hit the bulls eye. The concept was introduced in css because certain elements in the DOM could be targeted by multiple css rules. When the same property is defined in two separate css rules, specificity helps to determine which property will win the battle for dominance.
#Belgium me {...}
.country me {...}
When they developed css they tried to mimic regular specificity as much as possible, but they hit a few problems along the way. In simple cases though, it works just as expected. By using ids and classes they managed to come close to what we would logically expect. In the example above, the the first rule is more specific than the second because the id marks a unique instance of the class, meaning what is targeted by the id should be more specific, which is obviously the case.
This is the basic idea of css specificity, but it lacks one major aspect that regular specificity has.
proximity
.city .park me {...}
.planet .country me {...}
Consider the code above. In css, both rules have an equal weight because they both contain two classes. Because the second rule appears last it wins the battle of dominance. In the real world though, the first rule is considered to be more specific. It tells you I'm in a city park, the second rule only states I'm in country on this planet. Let's look at another example:
.country #Antwerp me {...}
#Belgium .city me {...}
Again, in css both rules have an equal weight because they both contain a class and id. In the real world , the fact that the first rule uses an id for city creates a greater specificity than when the id is used for country. And one final example:
.planet .country me {...}
.city me {...}
This example shows the problem is bigger than simply the order of our css statements. While the first rule appears to be more specific in css, in the real world the second rule would be considered the most specific of the two, as it manages to put a bigger limitation on my whereabouts.
What's lacking in css is the concept of proximity. The css language doesn't care how close (in the DOM) a class, id or html element is to "me", it merely sees how many of each are in a selector and computes a weight. Contrary to our everyday world, where proximity is pretty much crucial to determine the specificity of something.
time for revolution
So is css failing us? To truly answer this question we should work out a full model where proximity would be introduced in css. This is a bit too complex to do right away, but my gut feeling tells me that including (DOM) proximity would make things way more complicated. While it would probably be possible to create rules that lie closer to our own mental model of specificity, the clarity and ease of understanding of the current css model would probably be lost.
Maybe I'm wrong though, and some form of proximity could be easily included without completely messing things up, but that I'll leave to greater minds than myself. As for now, the issues that arise seem smaller than the trouble to go and change this core concept of the css language.
conclusion
Know that css specificity is different from what we normally understand when talking about specificity. I personally try to avoid the term specificity when dealing with css. I'd rather use "weight" to talk about selectors, as it comes closer to how it actually works in css. It doesn't make much of a difference, and from time to time I still find myself forgetting about the difference between both, but knowing where the exact difference lies surely helped me in conquering this pretty common mistake.

Comments
Bobby Jack
I totally agree (see this comment's URL for a similar post). Whilst full-blown proximity rules, as you suggest, might end up with very complicated style combinations, I certainly think a compromise is possible. For example, I don't see why an ID as the final part of a selector can't be considered 'more significant' than selectors with a non-ID part at the end.
Niels Matthijs
Wow, seems we even coined the same term!
Cool article, and I swear I didn't see it before launching my own. Maybe I'll try to do some research on it, seeing what could be captured in simple rules to introduce proximity without harming the simplicity of the current implementation.
jethro larson
CSS isn't intuitive. If you try to train someone from scratch you'll see that very quickly. Also the traversal modal differs greatly from how HTML is structured and DOM traversal works in JavaScript.
I find XPATH to be a more suitable for DOM selection but it's not very elegant.
Specificity is a complex problem. Maybe we could try coming up with something completely different from the CSS way as a thought experiment.
Mike
The thing is, we already have 'proximity' for real, twice over! Firstly we are able to use over-rides, like so: .country:rule1 .city:rule2 etc (this is called the cascade)
Secondly, the HTML itself gives you much the same ability.
Finally, I don't think that your example of planet>country>city really compares to the way that a page is ever built.