David Rozando
David Rozando

Reputation: 92

CSS: Nested declaration on child element is overridden by its parent nested declaration

I am having problem with nested CSS declarations for nested elements. Emm.. It's really hard to describe the problem, if you don't get what I mean, please just go to the jsfiddle link I provide below, you would understand what's the issue.

Here is the markup

<div class="red">
    <h1>should be red</h1>
    <div class="blue">
        <h1>should be blue</h1>
    </div>
</div>

and here is the CSS:

.blue h1 {
    color: blue;
}
.red h1 {
    color: red;
}

Notice that I put .blue h1 before the .red h1 declaration. But I have .blue element as a child of .red element. Please see the output on the jsfiddle. It shows wrong color on the .blue h1 element. However if I swapped the declaration into .red h1 first and then .blue h1, it's all fine. But I CAN'T do that in my real case and moreover if I swap the declaration, it won't work if the markup is also swapped. Vice versa.

http://jsfiddle.net/N7FcB/

Anyone got an idea how to solve this one?

PS: I know that having direct child selector will solve the problem. But I avoid to use it, because the element I am targeting (<h1>) is not always a direct child of the element with the class.

Thanks before :)

Update: Imagine I have this kind of declaration

.red h1 { color: red }
.green h1 { color: green }
.blue h1 { color: blue }
.gray h1 { color: gray }
/* and so on */

I can freely create my markup whether it's blue inside red or the opposite or gray inside red which is inside blue. It should work well in any conditions I write the nested markup.

Update: I think everyone does not really get what I am seeking here, please check out this new fiddle, it has better understanding of what I want. the first case is the false one, the 2nd case is the right one.

http://jsfiddle.net/kmMXW/9/

Upvotes: 1

Views: 1270

Answers (7)

Gabe
Gabe

Reputation: 1

Actually how many H1 do you need inside a div? i say not much. so why don't why give the class to the H1.

h1.red { color: red; }
h1.green { color: green; }
h1.blue { color: blue; }

Update

How about having a box with depth level, see fiddle http://jsfiddle.net/AnL7R/

by having linked classes you can override the upper one, e.g:

.blue,
.blue.first,
.blue.second
/*more depth class*/
{
    color: blue;
}

.red,
.red.first,
.red.second
/*more depth class*/
{
    color: blue;
}

Hope it helps

Upvotes: 0

ardhitama
ardhitama

Reputation: 1982

.blue > * {
color: blue;
}

.red > * {
    color: red;
}

You can always try ">" selector combined with wildcard

myfiddle

Upvotes: 0

oknoorap
oknoorap

Reputation: 1953

how about this?

div.red > h1 {
    color: red !important;
}

div.blue > h1 {
    color: blue !important;
}

or throw div element

.red > h1 {
    color: red !important;
}

.blue > h1 {
    color: blue !important;
}

http://jsfiddle.net/N7FcB/6/

Upvotes: 0

Alexandru Diacov
Alexandru Diacov

Reputation: 1191

Or maybe like that:

.red > h1 {
    color: red;
}
.blue h1 {
    color: blue;
}

fiddle.

This is 100%.

Upvotes: 0

Venu immadi
Venu immadi

Reputation: 1605

hope it will help you

.red > h1 {
color: red;
} 
.blue h1 {
color: blue;
}

select as direct child you will not face any more problem.

Upvotes: 0

Mr. Alien
Mr. Alien

Reputation: 157284

Browser reads your CSS from top to bottom and it will apply in the same way..

So first you have a rule called

.blue h1 {
    color: blue;
}

So browser will parse this information and will color your h1 as blue, but it goes ahead and it hits second selector which is

.red h1 {
    color: red;
}

Now, as your h1 which is nested inside .blue is further nested inside .red and also, the specificity of both the selectors are same, browser will go ahead and apply red to the inner h1.

So what's the solution?

If you can, just swap the order of your classes... No? You cannot? than use a specific selector..

div.blue h1 {
    color: blue;
}

Demo

The above selector is more specific compared to .red h1 as it has a class, and 2 elements... so here, browser will pick up first rule as it is more specific, thus overriding your .red h1 selector.

You can make your selectors specific as much as you need, you can write the above as div.red div.blue h1 or .red .blue h1, but just remember, the more specific selectors you use, the more you hit performance bar, also you will end up writing more and more specific selectors inorder to override others, so choose wisely..

Upvotes: 1

Nitesh
Nitesh

Reputation: 15739

If you do not want direct child selector, just add a parent reference for the nested elements. This will make your thing work.

You can add the below.

.red .blue h1 {
    color: blue;
}

WORKING DEMO

To enforce your div to render the color blue, you just need to add the reference of the element that you are using to the class.

for Instance,

div.blue h1 {
    color: blue;
}

WORKING DEMO - 2

In both cases, it will work.

Upvotes: 0

Related Questions