When CSS Doesn’t C

First off let me declare that I would not call myself a CSS “master” by any means.  I’ve had 2 incidents recently where CSS (Cascading Style Sheets) don’t appear to Cascade correctly and it is very, very frustrating.  Here’s a quick mockup of my code (abbreviated for brevity):

<div id="wrapper">
    <div class="rating">
        <a href=""><a/>
    </div>
</div>

And my CSS looks like this:

#wrapper a { position: relative; z-index: 1; }
.rating a{ position: absolute; z-index: 5; }

The problem I was having is that my <a> tag was getting the style applied from the ‘wrapper’ element instead of the ‘rating’ element.

The following rules for cascading order are taken from the w3.org, section 6.4.1:

  • Find all declarations that apply to the element and property in question, for the target media type. Declarations apply if the associated selector matches the element in question.
  • The primary sort of the declarations is by weight and origin: for normal declarations, author style sheets override user style sheets which override the default style sheet. For “!important” declarations, user style sheets override author style sheets which override the default style sheet. “!important” declaration override normal declarations. An imported style sheet has the same origin as the style sheet that imported it.
  • The secondary sort is by specificity of selector: more specific selectors will override more general ones. Pseudo-elements and pseudo-classes are counted as normal elements and classes, respectively.
  • Finally, sort by order specified: if two rules have the same weight, origin and specificity, the latter specified wins. Rules in imported style sheets are considered to be before any rules in the style sheet itself.

The first simply states that the element should only have the styles applied to it if the selector matches, and mine does.  The second doesn’t apply because both of my style elements are author defined and though they are in 2 separate CSS files, they are considered the “same origin”.  The third states that a more specific selector will override a more general one.  I would say that both of mine are equally “specific”.  And the fourth claims to sort by the order specified, which should apply because my ‘rating’ class is declared after the ‘wrapper’.

As far as I can tell I am meeting all of the criteria listed above, the only thing I can think of is that maybe the elements are weighted differently because the ‘wrapper’ is an ID where the ‘rating’ is a class, though I would have thought the fact that the ‘rating’ element is inside the ‘wrapper’ element would resolve that.  In the end I quit searching for rhyme or reason and threw “!important” on my ‘rating’ class and that straightened things out.  Thank goodness for tools like Firebug so you can immediately see how the styles are being applied.  I can only image how long something like this would have taken to track down in the olden days.

And if anyone out there is a CSS master and knows the ins and outs of why this is happening, please feel free to leave a comment.

This entry was posted on Thursday, January 22nd, 2009 at 12:59 pm and is filed under Code. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply