Home > other >  CSS properties inheritance and overriding in a nested HTML structure
CSS properties inheritance and overriding in a nested HTML structure

Time:11-04

Text in the snippet basically explains itself what I want to achieve. I want inner divs, that do not have a bg- class, to inherit border color, but then, if color changes, deeper divs then have that color inherited. I don't really have control over how deep nesting happens or how divs are structured and how (to which divs) color class names are assigned.

Using SCSS, so I have more colors and loop through them, but can't figure out how (if possible at all) to achieve such color inheritance.

Not sure if this is even possible to achieve easily, but here's what I have:

div {
  margin: 1em;
  padding: 1em;
  color: white;
}

div.area {
  border: 2px solid gray;
}

div.bg-orange {
  background-color: sandybrown;
  border-color: orange;
}

div.bg-orange .area:not([class*="bg-"]) {
  border-color: orange;
}

div.bg-red {
  background-color: lightpink;
  border-color: red;
}

div.bg-red .area:not([class*="bg-"]) {
  border-color: red;
}

div.bg-green {
  background-color: lightgreen;
  border-color: green;
}

div.bg-green .area:not([class*="bg-"]) {
  border-color: green;
}

div.bg-blue {
  background-color: lightblue;
  border-color: blue;
}

div.bg-blue .area:not([class*="bg-"]) {
  border-color: blue;
}
<div class="area bg-blue">
  <div class="area">Plain</div>
  <div class="area bg-green">
    Green
    <div class="area bg-red">Red</div>
    <div class="area">
      Should should be green border
      <div>Plain no border</div>
      <div class="area">Plain should be green border</div>
      <div class="area bg-red">
        Red
        <div class="area bg-orange">
          Orange
          <div class="area">Plain should be orange border</div>
        </div>
      </div>
    </div>
  </div>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Use CSS variables. The trick is that the custom property (the CSS variable) is inherited until you override it at a deeper level.

div {
  margin: 1em;
  padding: 1em;
  color: white;
}
div.area {
  border: 2px solid var(--c,gray);
}

div.bg-orange {
  background-color: sandybrown;
  --c: orange;
}

div.bg-red {
  background-color: lightpink;
  --c: red;
}
div.bg-green {
  background-color: lightgreen;
  --c: green;
}
div.bg-blue {
  background-color: lightblue;
  --c: blue;
}
<div class="area bg-blue">
  <div class="area">Plain</div>
  <div class="area bg-green">
    Green
    <div class="area bg-red">Red</div>
    <div class="area">
      Should should be green border
      <div>Plain no border</div>
      <div class="area">Plain should be green border</div>
      <div class="area bg-red">
        Red
        <div class="area bg-orange">
          Orange
          <div class="area">Plain should be orange border</div>
        </div>
      </div>
    </div>
  </div>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Is this the desired result?

I just replaced assigned color with inherit wherever you have .area:not([class*="bg-"]).

div {
  margin: 1em;
  padding: 1em;
  color: white;
}

div.area {
  border: 2px solid gray;
}

div.bg-orange {
  background-color: sandybrown;
  border-color: orange;
}

div.bg-orange .area:not([class*="bg-"]) {
  border-color: inherit;
}

div.bg-red {
  background-color: lightpink;
  border-color: red;
}

div.bg-red .area:not([class*="bg-"]) {
  border-color: inherit;
}

div.bg-green {
  background-color: lightgreen;
  border-color: green;
}

div.bg-green .area:not([class*="bg-"]) {
  border-color: inherit;
}

div.bg-blue {
  background-color: lightblue;
  border-color: blue;
}

div.bg-blue .area:not([class*="bg-"]) {
  border-color: inherit;
}
<div class="area bg-blue">
  <div class="area">Plain</div>
  <div class="area bg-green">
    Green
    <div class="area bg-red">Red</div>
    <div class="area">
      Should should be green border
      <div>Plain no border</div>
      <div class="area">Plain should be green border</div>
      <div class="area bg-red">
        Red
        <div class="area bg-orange">
          Orange
          <div class="area">Plain should be orange border</div>
        </div>
      </div>
    </div>
  </div>
</div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related