views:

635

answers:

5

I actually know how the browsers tend to render the following examples (results based on Opera 9.5 and Firefox 3.0), but I don't understand the reason behind them.

Take this example,

<style type="text/css">
#outer{color:red;}
.inner{color:blue;}
</style>

<div id="outer" class="outer">
    <div id="inner" class="inner">
     <span>testing</span>
    </div> 
</div>

The result is blue text.

However, now see this example,

<style type="text/css">
#outer span{color:red;}
.inner span{color:blue;}
</style>

<div id="outer" class="outer">
    <div id="inner" class="inner">
     <span>testing</span>
    </div> 
</div>

The text is now red.

Finally, try this,

<style type="text/css">
#outer span{color:red;}
#inner span{color:blue;}
</style>

<div id="outer" class="outer">
    <div id="inner" class="inner">
     <span>testing</span>
    </div> 
</div>

Once again we have blue text.

Is there a specific reason for this methodology?

(sorry about the unclear title, it's the best I could manage.)

+1  A: 

I hope this explanation helps:

EX 1) Because these are general rules, it applies the color of the immediate parent .inner

EX 2) An ID is more specific than a class (since there is only one element with a given ID) therefore the id selector is considered more specific and important

EX 3) Because the 2 rules are equally specific it chooses the last rule

Darko

Darko Z
The explanation of the third example is not correct. The styles apply to the span, not the parents.
Guffa
My bad - didn't read the code correctly. Have updated.
Darko Z
A: 

The cascade (the the 'C' in CSS) is well defined to allow a clear definition of what rules will take precedence (including allowing for important, user and agent rules).

But the rules are also not simple (thing of complex matches with large hierarchies specified).

The last step of the cascade is document order of the declaration, with last winning.

Richard
I think you mean the 'C' in CSS.
Sean Carpenter
D'oh!. Will correct.
Richard
A: 

In the first example the first style applies to the outer div. The inner div then inherits this style, but the second style applies to the inner div so it overrides the inherited style.

In the second example both styles apply to the span. The first style takes precedence because an id is more specific than a class.

In the third example both styles also apply to the span. As they have the same specificity, the last style takes precedence just because it's last.

You can read more about how precedence is determined here.

Guffa
+2  A: 

The W3C has a detailed explanation of exactly how CSS is supposed to cascade and take precedence. For your exact situation, this is what is occurring:

  1. While "color" is an inherited property, the inner selector targets the span itself, so it takes precedence.

  2. Since they both now target the span, the one that is more specific (the id selector) now takes precedence.

  3. They are now both equally specific, and thus the declaration that appears later takes precedence.

Daniel Lew
+2  A: 

In example 1 the span element is not specifically targeted, so we must look into how CSS Inheritance is handled. Color is an inherited property so we need to look at the span's parent elements for the most specific rule. In your example 1 case, that would be the rule with the ID (#) selector.

In example 2 the span element is specifically targeted, so we must look into the CSS Cascade to determine which of the rules that targets the element is most specific. Again, the ID selector wins.

In example 3 we invoke the CSS Cascade rules once again and since both are equal, last rule wins.

Note that in this situation:

 #outer {color: red; }
 span {color: blue; }

The text will be blue. This is because the second rule targets the element directly and therefore does not invoke the CSS Cascade.

More Reading:

Note and Disclosure: I authored the third blog post.

Carl Camera