<html>
<head>
<style type="text/css">
#red p {
color: #F00;
}
.blue {
color: #00F;
}
</style>
</head>
<body>
<div id="red">
<p>Should be a red paragraph</p>
<p class="blue">Should be a blue paragraph</p>
</div>
</body>
</html>
Why is the second paragraph still red? What’s the solution to make it blue?
In your stylesheet you are using #red p. The problem with this is that it targets all the p tags in the #red div and overrides your second line of css.
There are a number of ways to fix this, one of them is to give each <p> a class and target them individually like so:
<html>
<head>
<style type="text/css">
.red {
color: #F00;
}
.blue {
color: #00F;
}
</style>
</head>
<body>
<div id="p-wrapper">
<p class="red">Should be a red paragraph</p>
<p class="blue">Should be a blue paragraph</p>
</div>
</body>
</html>
Or a more advanced method is to add :first-child to the #red div like so (first-child as it’s name implies, will only target the first element of whatever you are selecting; in our case the <p> tag):
<html>
<head>
<style type="text/css">
#red p:first-child {
color: #F00;
}
.blue {
color: #00F;
}
</style>
</head>
<body>
<div id="red">
<p>Should be a red paragraph</p>
<p class="blue">Should be a blue paragraph</p>
</div>
</body>
</html>
Block level elements such as <div> and <h1>, <h2>, <h3> etc, have precedence over inline elements. You’ve given your <div> an id of #red and selected all the <p>'s in that div, and because you have given your <p> tag (an inline element) a class of .blue it doesn’t have as much precedence and is therefore ignored.
Both ‘#red p’ and ‘.blue’ are targeting the paragraph. There’s a conflict. One says it should be red, the other says it should be blue. Conflict resolution says … if one declaration lists more IDs than the other, that one wins.
‘#red p’ lists one ID, and ‘.blue’ lists no IDs. So ‘#red p’ wins, doing a victory jig over '.blue’s dead body, and the paragraph turns red.
If the red dec was just ‘#red’ without the ‘p’ then it would be a different story. Then the ‘#red’ declaration would not be specifically targeting the paragraph, but the paragraph’s parent. The default colour is ‘inherit’ (ie, whatever the parent is), so if nothing else is specified for the paragraph, it is red. But then you have ‘.blue’, which comes along and tells the paragraph not to inherit the colour of its parent, but instead to be blue. So then it’s blue.
Say what? Styling on block-level elements does not win out over styling on inline elements – in fact, it’s usually the other way round.
p {color:red;}
span {color:green;}
<p>Here's a red paragraph <span>with some green words</span> in the middle</p>
Styling declared on the inline element will almost always overrule styling declared on the parent element, because it’s targeting the actual element rather than its parent.
A <p> is a block-level element anyways (was coding a WP theme for a client while I posted that, multi-tasking was never one of my strong suits ). Totally messed that up, don’t know what I was thinking .
Am sorry I think I have missed most of the post, the answer here is SPECIFICITY. I has nothing to do with block or inline.
SPECIFICITY overrules the cascade… no matter what!
That means :
A class will overrule a tag in the style sheet, an ID will in turn overrule a class and if you should ( perish the thought) write your CSS in the mark-up inside the tag itself it will overrule EVERYTHING ELSE.
By the described order above : #red p {} will override rules like : p{}( a tag), .blue {}(a simple class), and even p.blue{} ( a class and tag) since you started with an ID and a tag… in order to override that rule… you will need AT LEAST an ID and a tag. #red p {} (will target all the Ps and its not what we want so we need something like #red .blue {}
expounding on this:
if you had written:
.red p {}
.blue{}
it will would not work as a class+ a tag is still > just a class
HOWEVER this would work
.red p {}
p.blue{}
AND THIS would not.
p.blue{}
.red p {}
when the specificity total is the same (class+tag)=(class+tag) then rule that is latter the stylesheet wins.
Yes, and the reason is one of specificity. An id (#) carries a lot more weight than a class (.), so the id wins out. So to make the override more specific, you have to include an id. It’s now more specific because it contains an id and a class, which has more weight than just an id.
I’d still go with the simpler solution, though, unless you must support IE6. Even then, you could put the IE6 style in a separate, IE-only style sheet, or serve it up with a hack, such as
* html #firstdiv p {margin-bottom: 30px;}
* html #firstdiv .seconddiv p {margin-bottom: 0;}
Because !important is really !important… but it is better not to use it unless you have a terrific reason for it… and no, setting up the size of the characters is not a good reason
I learned something reading this. I always though the cascading nature of CSS dictated that whatever rule came last won. I guess that isn’t true. Thanks.
That only happens when both rules have the same specificity level. Of course, you only notice it when you’re trying to style the same property for the same element in bothy rules