As you are probably aware:
.blue p
will select any p tags within a .blue class.
.red p
will select any p tags within a .red class.
Your <p> first </p>
is inside a blue class, so it matches the .blue p
rule and displays as blue.
<div class="red">
is within both a red and a blue class, causing a conflict. CSS resolves this by using the last rule encountered, which in this case is the .blue p
rule, resulting in the text being displayed in blue.
CSS solution
If p tags will always be direct children of your color classes, you can use the following solution. The >
indicates a descendant selector that only targets immediate descendants.
.red > p {
color: red;
}
.blue > p {
color: blue;
}
Alternate CSS fix
You may also follow the suggestion from Tom. This method works because more specific CSS rules take precedence over less specific ones. Even though the blue rule comes later, the div .red p
has two classes and is therefore more specific than .blue p
.
.red p,
.blue .red p {
color: red;
}
.blue p,
.red .blue p {
color: blue;
}
However, this just shifts the issue one level deeper. The red class in the given HTML snippet will still appear blue.
<div class="blue">
<div class="blue">
<p> first </p>
<div class="red">
<p> second </p>
</div>
</div>
</div>
HTML adjustment
This simpler approach involves moving your classes to the p tags:
<div>
<p class="blue"> first </p>
<div>
<p class="red"> second </p>
</div>
</div>
Other considerations
There are various ways in which CSS rules can be overridden. It would be beneficial for you to explore CSS specificity.