Home > OS >  Can you make the distance between selectors matter for specificity in CSS?
Can you make the distance between selectors matter for specificity in CSS?

Time:08-20

Originally split off from this question.

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

.blue {
    color: blue;
}

.green {
    color: green;
}
<div >
    <!-- more divs with color classes -->
        <div >
            <div>
                <!-- Unknown depth without color classes -->
                    <div>
                        <div >
                            <span>Hello World</span>
                        </div>
                    </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):

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

.green .my-component {
    color: green;
}
<div >
    <!-- more divs with color classes -->
        <div >
            <div>
                <!-- Unknown depth without color classes -->
                    <div>
                        <div >
                            <span>Hello World</span>
                        </div>
                    </div>
                <!-- -->
            </div>
        </div>
    <!-- -->
</div>

I understand why this is (specificity; see Can a component be styled based on its closest parent in pure CSS?) but would like to know how to work around it.

Is there a way to get the second example to behave as the first (only using CSS/HTML)?

CodePudding user response:

Use CSS variables. The closest class will override all the previous ones and win the game.

.blue {
    --c: blue;
}
.green  {
    --c: green;
}

.my-component {
  color: var(--c);
}
<div >
    <!-- more divs with color classes -->
        <div >
            <div>
                <!-- Unknown depth without color classes -->
                    <div>
                        <div >
                            <span>Hello World</span>
                        </div>
                    </div>
                <!-- -->
            </div>
        </div>
    <!-- -->
</div>

CodePudding user response:

Fight specificity with specificity.

UPDATE: use the default :root selector as a starting point, to override other rules.

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

.green .my-component {
    color: green;
}
<div >
    <!-- more divs with color classes -->
        <div >
            <div>
                <!-- Unknown depth without color classes -->
                    <div>
                        <div >
                            <span>Hello World</span>
                        </div>
                    </div>
                <!-- -->
            </div>
        </div>
    <!-- -->
</div>

  • Related