Reputation: 85653
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;
}
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
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
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
Reputation: 11033
#header ul.menu
sets 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
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
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
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