Home > OS >  Can a component be styled based on its closest parent in pure CSS?
Can a component be styled based on its closest parent in pure CSS?

Time:08-20

If I use this css, the span's text color is determined by its closest parent (i.e. text is blue):

.red {
    color: red;
}

.blue {
    color: blue;
}

.green {
    color: green;
}
<div >
    <div >
        <div >
            <div >
                <span>Hello World</span>
            </div>
        </div>
    </div>
</div>

However, I want this behavior for .my-component specifically. I therefore added .my-component to my selector but suddenly, the span's text color is determined by the definition order (i.e. text is green):

.red .my-component {
    color: red;
}

.blue .my-component {
    color: blue;
}

.green .my-component {
    color: green;
}
<div >
    <div >
        <div >
            <div >
                <span>Hello World</span>
            </div>
        </div>
    </div>
</div>

Why is this?

EDIT

Ok, so I messed up a bit here. As noted in the comments, I was mostly surprised that the distance between .red and .my-component did not affect specificity. However, my second question was the one I was really interested in. This question has already received a lot of great answers to the first question, so I'm reverting this question to its original state and will split the second question off into a new one. Thank you all for the great answers!

CodePudding user response:

Given that the question was (originally) titled: "Can a component be styled based on its closest parent in pure CSS?" and looking at the original examples given you can do it like this:

.red > .my-component {
    color: red;
}

.blue > .my-component {
    color: blue;
}

.green > .my-component {
    color: green;
}
<div >
    <div >
        <div >
            <div >
                <span>Hello World</span>
            </div>
        </div>
    </div>
</div>

The > demands a direct parent-child relationship. A "grandparent" will have no effect on the target element's formatting.

However, the above snippet will not work if the target div is placed several levels under the innermost "colored" div.

CodePudding user response:

This is all determined by Specificity:

Specificity is the algorithm used by browsers to determine the CSS declaration that is the most relevant to an element, which in turn, determines the property value to apply to the element. The specificity algorithm calculates the weight of a CSS selector to determine which rule from competing CSS declarations gets applied to an element.

With this being said, you can use more specific selectors such as the child combinator > with reference to the element to specify styles. You'll notice the more specific I get with the selectors that it will take precedence over other styles.

.red .my-component {
  color: red;
}

.blue > .my-component span {
  color: blue;
}

.green .my-component {
  color: green;
}
<div >
  <div >
    <div >
      <div >
        <span>Hello World</span>
      </div>
    </div>
  </div>
</div>

If I were to use .green > .red > .blue > .my-component span in the last part of the CSS then this would take precedence because it is more specific. An example of that is below.

.red .my-component {
  color: red;
}

.blue > .my-component span {
  color: blue;
}

.green > .red > .blue > .my-component span {
  color: green;
}
<div >
  <div >
    <div >
      <div >
        <span>Hello World</span>
      </div>
    </div>
  </div>
</div>

CodePudding user response:

So this happens because the code below:

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

influences the color of the element and its children. Since one children is inside the another and CSS selectors here have the same priority then the one that is the cloest (the last) has the final word. The color value is inherited but every time changed because of your classes. That's why the sequence in html has a meaning.

.red .my-component {color: red;}
.blue .my-component {color: blue;}
.green .my-component {color: green;}

In the second case you are targeting only .my-components inside the proper class elements so when you change color to red, you are then changing it to blue and at last to green. That's why the sequence in css file has a meaning and not in html.
I hope this will help.

  • Related