jeffkee
jeffkee

Reputation: 5238

CSS cascading order within one stylesheet

I'm trying to figure out if I'm totally mis-understanding something here. I have a menu and submenu (dropdown style using only CSS, no javascript) and for some reason the sub-menu styles (defined by .submenu li a) always shows up at the same style as the parent a (defined by #menu li a) even though the submenu CSS styles show up AFTER the top menu styles.

Am I mis-understanding CSS rules? I thought features defined LATER and at a lower level override the top level (for example, inline style will always override style.css styles). I'm attaching a screenshot off Firebug that shows crossing out the font sizes defined on line 275 in favour of styles defined at line 225, on the parent DOM objects.

firebug screenshot

My DOM looks like this to simplify it:

<ul id="menu">
    <li>
        <a href="http://themes.brixwork.com/westend/about-us">about us</a>
        <ul class="submenu">
            <li>
                <a href="http://themes.brixwork.com/westend/testimonials">Testimonials</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="http://themes.brixwork.com/westend/listings">listings</a>
    </li>
    <li>
        <a href="http://themes.brixwork.com/westend/mls-search">MLS&reg; Search</a>
    </li>
    <li>
        <a href="http://themes.brixwork.com/westend/city-guide">City Guide</a>
        <ul class="submenu">
            <li>
                <a href="http://themes.brixwork.com/westend/city-guide/7/the-west-end-vancouver">The West End</a>
            </li>
            <li>
                <a href="http://themes.brixwork.com/westend/city-guide/8/coal-harbour">Coal Harbour</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="http://themes.brixwork.com/westend/blog">blog</a>
    </li>
</ul>

And my CSS looks like this.

#menu li a:link, #menu li a:visited {
    color:#333;
    text-decoration:none;
    font-size:16px;
    font-weight: bold;
    padding-bottom: 3px;
    text-transform: uppercase;
}

#menu li a:hover {
    color:#333;
    background-image: url('../images/pink_dots.png');
    background-position: bottom left;
    background-repeat: repeat-x;
}

#menu li a:active {
    position:relative;
    color:#333;
}

.submenu {
    position:absolute;
    left: -9999px;
    display: block;
    background-color: #DD2D77;
    padding:0px 0px 0px 0px;
    margin: 0px;
    top:16px;
    z-index: 20;
}

#menu li:hover .submenu {
    left: -5px;
}

.submenu li {
    text-align: left !important;
    margin:0px !important;
    padding: 2px 0px 3px 0px !important;
    position:relative;
    display: block;
    width: auto;
    float: none;
    text-align: left;
}

.submenu li:hover {
}

.submenu li a:link, .submenu li a:visited {
    color:#fff;
    text-align: left;
    font-size:12px;
    font-weight: normal;
    margin: 0px;
    white-space:nowrap;
    display: block;
    padding:3px 7px 5px 7px !important;
    min-width: auto;
    zoom: normal;

}

.submenu li a:hover, .submenu li a:active {
    color:#fff !important;
    background-image: none !important;
    background-color: #73AA12;
}

Upvotes: 1

Views: 941

Answers (4)

PhillipKregg
PhillipKregg

Reputation: 9358

Here is a specificity calculator that you can add as a bookmark in your browser: http://www.westciv.com/mri/

When you click it, it will open a window that you can either type a selector into, or you can click an element on the page and it will suggest the selector that you should use (showing you the path it took to get there).

It may help as a learning tool.

Upvotes: 0

swatkins
swatkins

Reputation: 13630

You're correct in saying that rules declared later in the cascade take precedence but only if they are at an equal or higher specificity.

Your first style #main li a uses an ID as the context whereas the second style .submenu li a uses a CLASS as the context. An ID holds more specificity than the CLASS, so it overrides the .submenu.

You need to read up a bit on CSS Specificity:

You could do a quick fix and declare #main > li a - which will only apply to anchors inside list items that are direct descendants of the #main element. Then, your .submenu li a rule will be applied to your submenu items.

Upvotes: 2

Ross Smith
Ross Smith

Reputation: 755

Yes; you are misunderstanding how CSS works.

http://www.htmldog.com/guides/cssadvanced/specificity/

The order in which you define rules in the CSS file means nothing. The selector determines which rules apply and when.

The axiom behind CSS is - the more specific your selectors are, the more precedence they take over less specific ones.

This is how anchor styles work for instance. To show an underline only on hover:

a:hover
{
  text-decoration: underline;
}

a
{
  text-decoration: none;
}

Even though the less specific rule is defined later, the more specific rule (an anchor tag that is also mouse hovered) overrules the more general rule.

Upvotes: 2

alex
alex

Reputation: 490243

The id selector has more specificity than your other selector.

Increase the specificity, which is favoured over !important.

Upvotes: 2

Related Questions