Chris Seufert
Chris Seufert

Reputation: 869

CSS Controlling Cascade

I have built an editor for users to use, it has a pallette of styles to choose from, for this example we'll call these .p1 and `.p2'. The problem i have is that they are overriding each other depending on what order they appear in the style sheet.

I cant find a way that is going to solve this, because i do not know how these panels may be nested.

This example is significantly simplified, and I cannot control exactly where things like the a tag will be, they could be nested in tables, lists, paragraphs, or any other tags, at any depth. This would also apply to headings and any other child elements that need there style customized (eg H1, ul...) to look good in the context that it is shown in.

.p1 a {
  color: red;
}
.p2 a {
  color: green;
}
<div class="pl p2">
  <a href="#">Hello 2</a>
  <div class="pl p1">
    <a href="#">Hello 2-1</a>
    <div class="pl p2">
      <a href="#">Hello 2-1-2</a>
    </div>
  </div>
</div>
<div class="pl p1">
  <a href="#">Hello 1</a>
  <div class="pl p2">
    <a href="#">Hello 1-2</a>
    <div class="pl p1">
      <a href="#">Hello 1-2-1</a>
    </div>
  </div>
</div>

I have played around with :not selector, and also using all:default, on children, but have had no luck.

Upvotes: 8

Views: 92

Answers (2)

vals
vals

Reputation: 64164

Your example is a little confusing because it has 2 classes applied to the same element.

If I understand you correctly, you want that the a element is styled by the nearest ancestor in the DOM.

If this is the case, the solution would be to set a set of rules, where the ancestors that have one of the 2 classes will always match, and so the rule with the highest specifity will win....

Sorry, but I can't find a better way to explain it...

.p1 a, 
*[class^=p] .p1 a, 
*[class^=p] *[class^=p] .p1 a, 
*[class^=p] *[class^=p] *[class^=p] .p1 a 
{
	background-color: antiquewhite;
}

.p2 a, 
*[class^=p] .p2 a, 
*[class^=p] *[class^=p] .p2 a, 
*[class^=p] *[class^=p] *[class^=p] .p2 a 
{
	background-color: lightblue;
}
<div class="p2">
  <a href="#">Hello 2</a>
  <div class="p1">
    <a href="#">Hello 2-1</a>
    <div class="p2">
      <a href="#">Hello 2-1-2</a>
    </div>
  </div>
</div>
<div class="p1">
  <a href="#">Hello 1</a>
  <div class="p2">
    <a href="#">Hello 1-2</a>
    <div class="p1">
      <a href="#">Hello 1-2-1</a>
    </div>
  </div>
</div>

Upvotes: 2

Maximillian Laumeister
Maximillian Laumeister

Reputation: 20359

It looks like what you may be looking for is the direct child selector >. Learn more about the direct child selector on MDN.

Live Demo:

.p1 > a {
  color: red;
}
.p2 > a {
  color: green;
}
<div class="pl p2">
  <a href="#">Hello 2</a>
  <div class="pl p1">
    <a href="#">Hello 2-1</a>
    <div class="pl p2">
      <a href="#">Hello 2-1-2</a>
    </div>
  </div>
</div>
<div class="pl p1">
  <a href="#">Hello 1</a>
  <div class="pl p2">
    <a href="#">Hello 1-2</a>
    <div class="pl p1">
      <a href="#">Hello 1-2-1</a>
    </div>
  </div>
</div>

Upvotes: 3

Related Questions