3

The goal is to have an element's parent dictate it’s style. So .dark .light p would have light text, .dark p would have dark text, and .light .dark .light p would have light text.

The p element might not even be a direct child of .dark or .light so .light .dark div.wrap div.inner p would have dark text.

Because of the cascading nature of CSS, it seems to prefer the last rule. Is this even possible?

/* Doesn't work - switching the order isn't helpful
   as the opposite problem occurs */

.dark p {
  color: #000;
}
.light p {
  color: #aaa;
}
/* Works, but in my use case I need to specify attributes on 
   specific element. */

/* 
.dark {
  color: #000;
}

.light {
  color: #aaa;
} 
*/

/*  Works but not realistic if paragraph is nested deeper */

/*
.dark > p {
  color: #000;
}

.light > p {
  color: #aaa;
}
*/

/* Only works on the first two levels */

/* 
.dark p {
  color: #000;
}

.light p {
  color: #aaa;
}

.dark .light p {
  color: #aaa;
} 

.light .dark p {
  color: #000;
} 
*/
<div class="light">
  <p>Light text</p>
  <div class="dark">
    <p>Dark text</p>
    <div class="light">
      <p>Light text</p>
    </div>
  </div>
</div>

<div class="dark">
  <p>Dark text</p>
  <div class="light">
    <p>Light text</p>
    <div class="dark">
      <p>Dark text</p>
    </div>
  </div>
</div>

http://codepen.io/acondiff/pen/KaaqxP

8
  • I am not sure what you are trying to do here? Classes and the !important tags are preferable to so many different rules. Commented Jan 18, 2017 at 22:24
  • 2
    A partial solution: codepen.io/anon/pen/QddMXv Commented Jan 18, 2017 at 22:25
  • Nice try vals. I was aware I could do that, but after five or six levels it would become very unmanageable especially in large projects. It might also override things like :hover. Commented Jan 18, 2017 at 22:28
  • 1
    @scoopzilla !important is the ultimate last resort, avoid it like the plague. That would not help here either, would it? Commented Jan 18, 2017 at 22:30
  • I don't think this is a CSS problem, but an HTML problem. the markup is mixed up and poorly organized. This problem wouldn't exist with better structured markup. You could have p.light and p.dark and eliminate all the redundant divs Commented Jan 18, 2017 at 22:40

5 Answers 5

3

CSS follows the flow of the css document, therefore if .dark comes after .light in the CSS file, any element in your html with both classes will always display the .dark style.

.light {
  background: #ccc;
  }
.dark {
  background: #999;
  }
<p class="dark light">This will be dark  as it comes after light in the css file.</p>

!important

You can override the .dark styles by putting !important on your .light styles.

.light {
  background: #eee !important;
  }
.dark {
  background: #999;
  }
<p class="light dark">This will be light as the light styles has !important</p>

Alternatively you can apply the light styles to all elements and just override the elements you need to:

p {
  background: #eee;
}
.dark {
  background: #999;
}
<p>this will be light</p>

<p class="dark">this will be dark</p>

Sign up to request clarification or add additional context in comments.

1 Comment

As mentioned earlier, only use !important as a last resort. There are a lot of different components within .light and .dark that I want styled. I would much prefer to simply add a class to it's parent that changes the background color and styles it's children to look good on that background color rather than applying classes to everything. That would seem very repetitive and unnecessary.
1

Consider giving the same color to all text elements.

Then overriding the color for either light or dark.

body {
  color: red;
}
.light > p {
  color: blue;
}
<div class="light">
  <p>Light text</p>
  <div class="dark">
    <p>Dark text</p>
    <div class="light">
      <p>Light text</p>
    </div>
  </div>
</div>

<div class="dark">
  <p>Dark text</p>
  <div class="light">
    <p>Light text</p>
    <div class="dark">
      <p>Dark text</p>
    </div>
  </div>
</div>

3 Comments

The problem still exists if you remove the >. The nesting level can vary. This will be used to theme react components depending on what background color they appear on. For example, I want to give a textarea a dark background color if it appears on a light background and a light background color if it appears on a dark background.
Then maybe you should focus more on specificity and less on the cascade. Since the color property is inheritable relying on the cascade can be tricky. Just give target elements a higher specificity.
Maybe color was a bad example then. I am primarily changing background-color and border-color in the application I am developing. I could always add a class like on-dark-bg or on-light-bg to the element itself but wheres the fun in that?
0

The following code will work by covering the nesting nature of the code.

.dark p {
    color: #000;
}
.light p {
    color: #aaa;
}

.dark .light>p{
    color:#aaa;
}
.light .dark>p{
    color: #000;
}

1 Comment

Again, it may not be a direct child of .dark or .light. It may look something like .light > .wrap > .dark > .inner > .card > .content > p.
0

Try this :

.dark > p {
            color:#000;
         }


.light > p {
            color:#aaa;
         }

Full code :

.dark > p {
	color:#000;
}
			
.light > p {
	color:#aaa;
}
<div class="light">
  <p>Light text</p>
  <div class="dark">
    <p>Dark text</p>
    <div class="light">
      <p>Light text</p>
    </div>
  </div>
</div>

<div class="dark">
  <p>Dark text</p>
  <div class="light">
    <p>Light text</p>
    <div class="dark">
      <p>Dark text</p>
    </div>
  </div>
</div>

Comments

0

I approached this problem by setting up the HTML a bit differently. This gives enough flexibility for two levels.

.light { color: black; background:lightgrey;}
.dark {color: grey; background: black;}
div.light {color: black}
<section class="dark">
 <p>Lighttext</p>
 <div class="light">
   <p>Dark text</p>
 </div>
</section>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.