htmlcsscss-selectorscss-specificitycss-cascade

CSS precedence logic


In this example:

http://jsfiddle.net/Ja29K/

<style>
  /* Default links */
  a {
    color: #0F0; /* Green */
  }

  /* Header links */
  #header a {
    color: #F00; /* Red */
  }

  /* Login link */
  #login {
    color: #00F; /* Blue */
  }
</style>

<header id="header">
  <p><a href="#">header link</a> is red</p>
  <p><a id="login" href="#">login link</a> is not blue</p>
</header>

Is not logical that the login link must be blue?

I know that the declarations have the same origin and same importance, so they need to be scored (selector's specificity).

To calculate selector specificity I created an table for each selector:

A = Number of inline styles: 0
B = Number of ID: 0
C = Number of classes: 0
D = Number of elements: 0

So the login element have 3 collisions related to his color: a, #header a, #login

element (A, B, C, D)

a (0, 0, 0, 1) = 1
#header a (0, 1, 0, 1) = 101
#login (0, 1, 0, 0) = 100

The selector "#header a" wins because it had the biggest score.

But

If we change the selector "#login" to "a#login", we will have:
a#login (0, 1, 0, 1) = 101
The selector "#header a" looses, because with a draw wins the last that was declared.

So, the thing that I can't understand is:

Since "#header a" selector refers to many elements and an ID selector (e.g. #login) just refer one element, is logical that we want to apply ID selector declarations to that element, right? I really can't understand this CSS precedence logic, because I think ID selector must be basically the most specific thing possible, just like inline styles.

P.S.: Sorry for my bad english :)


Solution

  • You can't see "specificity" in a sense of which selector targets the fewest elements but simply what is most important.

    Of course could the rules have been made even more complicated by differentiating such things like #header a or a#login. However this just would add more confusion to the whole system.
    Also most likely this (c/w)ould be abused like the following: header#header a - this added a higher specificity but also could target more elements.

    In my opinion this would add no further value to the system but only make it more complicated.

    When writing CSS one should always try to keep the rules as short as possible for performance issues. If you need to overwrite a rule you still have the possibility to add another id or class - in addition to the normal cascading this is really more than enough.