Reputation: 33
here is a fiddle with the problem:
https://jsfiddle.net/c2exs2f7/3/
How does the second "blue" stay like the first instance (it should have color: white
) without changing the HTML structure?
HTML
<div class="blue">
<div class="content">
<div class="label">blue</div>
<div class="yellow">
<div class="content">
<div class="label">yellow</div>
<div class="blue">
<div class="content">
<div class="label">blue</div>
</div>
</div>
</div>
</div>
</div>
</div>
SCSS
// Skip until...
div {
border-radius: .25em;
padding: .5em;
font-family: helvetica, sans-serif;
}
// ...here:
.blue {
background-color: hsl(220,100%,50%);
.content {
color: white;
}
}
.yellow {
background-color: hsl(60,100%,50%);
.content {
color: hsl(0,0%,10%);
}
}
EDIT #1
Thank you guys for these fast responses!
I am working on a grid system where I am able to nest different grid systems (with different CSS values).
Upvotes: 3
Views: 1518
Reputation: 85
Since the most inner label has no siblings, you can do the following:
.blue .label:only-child {
color: white;
}
The :only-child
CSS pseudo-class represents an element without any siblings
Upvotes: 0
Reputation: 347
I had this same issue where the HTML nesting varies and so it's not possible to make more specific selectors due to overwhelming complexity and non-DRY code.
Here's the solution I came to:
https://jsfiddle.net/cg0u8v1s/
Basically, a systematic approach to the class names is key so you can use a CSS attribute selector reliably (although I'd recommend a more unique naming convention than "color-" as it's too generic.).
Example:
.color-blue {
&,
[class*="color-"] &,
[class*="color-"] [class*="color-"] & {// Only needed if you want a 3rd level of nesting to work.
background-color: blue;
.content {
color: skyblue;
}
}
}
.color-yellow {
&,
[class*="color-"] &,
[class*="color-"] [class*="color-"] & {// Only needed if you want a 3rd level of nesting to work.
background-color: yellow;
.content {
color: brown;
}
}
}
This will output selectors that become more specific with nesting without the need for non-DRY code or having to use !important.
The CSS output will look like this:
.color-blue,
[class*="color-"] .color-blue,
[class*="color-"] [class*="color-"] .color-blue {
// code...
}
Upvotes: 0
Reputation: 240938
The selectors .yellow .content
and .blue .content
have the same specificity (20 in this case), therefore the selector that appears later in the stylesheet will override the first one due to the cascading nature of a stylesheet. In this case, the selector .yellow .content
is overriding .blue .content
, which is why the nested .blue
element is black.
One quick solution would be to select nested .blue
element with the selector .blue .blue
:
.blue,
.blue .blue {
background-color: hsl(220,100%,50%);
.content {
color: white;
}
}
An arguably better approach would be to only select direct .content
children elements using the child selector, >
:
.blue {
background-color: hsl(220,100%,50%);
> .content {
color: white;
}
}
.yellow {
background-color: hsl(60,100%,50%);
> .content {
color: hsl(0,0%,10%);
}
}
Based on your comments, the ordering/layering of the elements may vary. An alternative solution would be to set the color
property on the .blue
/.yellow
element and then set the color
property of the children elements to inherit
:
Updated Example - this seems to work for all variants.
.blue {
background-color: hsl(220,100%,50%);
color: white;
.content {
color: inherit;
}
}
.yellow {
background-color: hsl(60,100%,50%);
color: hsl(0,0%,10%);
.content {
color: inherit;
}
}
Upvotes: 2
Reputation: 1018
You can't. Not with inherent anyway. Because the second blue will inherent from the yellow. So if u want all blue always have white letters and yellow always black letters. Why not just put:
.blue { color: #fff; }
.yellow { color: hsl(0,0%,10%); }
And you won't need the ".content" wrapper.
Upvotes: 0
Reputation: 10015
See https://jsfiddle.net/c2exs2f7/4/
What I did was to enforce inheritance only for the child content
classed DIV, not the entire descendance.
Applying the immediate children operator >
in the SCSS makes the .content
div to consider only its immediate parent color.
Go on and try nesting more DIV
s, you will see that it works.
Upvotes: 1