Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85653

css selector not working without its class

HTML:

<div id="header">
    <div id="one">
        <ul class="menu">
            <li>one text</li>
        </ul>
    </div>
    <div id="two">
        <ul class="menu">
            <li>one text</li>
        </ul>
    </div>
</div>

This css won't work

#header ul.menu{
    background-color: red;
    text-align: left;
}
#two ul{                     /*this line*/
    background-color: blue;
    text-align: right;
}

This css work

#header ul.menu{
    background-color: red;
    text-align: left;
}
#two ul.menu{                /*this line*/
    background-color: blue;
    text-align: right;
}

demo

Why is this so?

Update

As per answers on css specificity #header ul.menu is more specific than #two ul. I got it carefully ul.menu is more specific than ul.

ul.menu{...}
#two ul{...} /* works exactly, yes #two is more specific than ul.menu */

Okay, Change the order

order 1:

#header ul.menu{
    background-color: red;
    text-align: left;
}
#two ul.menu{                   /* this selector works as per the specificity */
    background-color: blue;
    text-align: right;
}

Why #two ul.menu is more specific than #header ul.menu? (Demo is not required for this as top first demo shows this)

order 2:

#two ul.menu{
    background-color: blue;
    text-align: right;
}
#header ul.menu{                /* this selector works as per the specificity */
    background-color: red;
    text-align: left;
}

Why #header ul.menu is more specific than #two ul.menu? demo

Upvotes: 2

Views: 216

Answers (6)

BoltClock
BoltClock

Reputation: 724592

That's because the class selector in #header ul.menu makes it more specific than #two ul, even though #two is "closer" to the ul in terms of structure. Specificity doesn't care how "close" one element is to another. It doesn't even count combinators, so even if you used #two > ul it wouldn't make a difference.

If you're going to select the same element, there is no reason not to balance your selector for specificity and either keep the class selector in both rules:

#header ul.menu{
    background-color: red;
    text-align: left;
}
#two ul.menu{
    background-color: blue;
    text-align: right;
}

Or remove it from both rules:

#header ul{
    background-color: red;
    text-align: left;
}
#two ul{
    background-color: blue;
    text-align: right;
}

Depending on your needs.


In your update you've simply switched the two equally specific rules around. The later rule always overrides the earlier rule. Again, this is regardless of element structure.

Upvotes: 6

thgaskell
thgaskell

Reputation: 13256

Why #header ul.menu is more specific than #two ul.menu?

The selectors have the same specificity. When this happens, the one that was declared last wins.

Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins. Declarations in imported style sheets are considered to be before any declarations in the style sheet itself.

Source: http://www.w3.org/TR/CSS2/cascade.html#cascading-order

Upvotes: 0

mahatmanich
mahatmanich

Reputation: 11033

#header ul.menusets the background color for all ul.menu items in your DOM tree beneath #header. So it has a higher css weight as opposed to #header ul or #two ul

Look at how cascading in css actually works and how the weighing is applied.

You could also run without any ul and just use the #id .class and it would work.

#header .menu{
    background-color: red;
    text-align: left;
}
#two .menu{
    background-color: blue;
    text-align: right;
}

Upvotes: 0

Roy M J
Roy M J

Reputation: 6948

You should mention full heirarchy, like #header div ul.menu

The following will work :

#header div ul.menu{
    background-color: red;
    text-align: left;
}

Then if you want a particular div inside the header to have different css styles, replace div with the id or unique class of that particular div.

#header #two ul.menu{
    //some styles just for menu inside #two
}

Fiddle : http://jsfiddle.net/M5pLZ/3/

Cheers

Upvotes: -1

Slavenko Miljic
Slavenko Miljic

Reputation: 3856

That's because you have the line #header ul.menu which is more 'specific' so it uses those styles. Either use #one ul instead #header ul or use #two ul.menu

Upvotes: 2

Mathew Thompson
Mathew Thompson

Reputation: 56459

That's because the first selector:

#header ul.menu

Is a more specific match than:

#two ul

Because it contains a class selector as well as a type selector, therefore will be overriden by the styles applied using the top selector.

Upvotes: 3

Related Questions