Search code examples
csscss-variables

Is there a way to reproduce currentColor with var(--current-color)?


I don't use currentColor very often but when I do, it's extremely useful.

So I've been a little excited about the arrival of CSS Variables.

Let's take a traffic light.

N.B. Please take it on trust from me that Japanese traffic lights go red to amber to blue. I know it's hard to believe. I know the blue light looks sort-of green. But it isn't, it's blue.

div {
float: left;
width: 200px;
}

div div {
float: none;
}

.top {
color: rgb(255,0,0);
}

.middle {
color: rgb(255,227,0);
}

.bottom {
color: rgb(63,255,63);
}

.jp .bottom {
color: rgb(0,255,191);
}

.light {
text-align: center;
}

.light::before {
content: '';
display: block;
margin: 6px auto 0;
width: 25px;
height: 25px;
border-radius: 15px;
background-color: currentColor;
}
<div class="uk">
<h2>UK Traffic Lights</h2>
<div class="top light">Red</div>
<div class="middle light">Amber</div>
<div class="bottom light">Green</div>
</div>

<div class="jp">
<h2>JP Traffic Lights</h2>
<div class="top light">Red</div>
<div class="middle light">Amber</div>
<div class="bottom light">Blue</div>
</div>

Now, the clever thing about

background-color: currentColor;

is that it just reads whatever the current value for color is and uses that.

By contrast...

background-color: var(--current-color);

That can't reference the current value of another style declaration, can it?

So, you'd need to set up 4 variables (just like you need to declare color: 4 times in the styles above):

.top {
--color-top: rgb(255,0,0);
}

.middle {
--color-middle: rgb(255,227,0);
}

.bottom {
--color-bottom: rgb(63,255,63);
}

.jp .bottom {
--color-bottom-jp: rgb(0,255,191);
}

And then... you need to reference each of those different variables later on. Which means a different background-color declaration for each variable:

.top::before {
color: var(--color-top);
background-color: var(--color-top);
}

.middle::before {
color: var(--color-middle);
background-color: var(--color-middle);
}

.bottom::before {
color: var(--color-bottom);
background-color: var(--color-bottom);
}

.jp .bottom::before {
color: var(--color-bottom-jp);
background-color: var(--color-bottom-jp);
}

Really?!

That can't be right. Have I missed something?

Is there no way to reproduce currentColor with var(--current-color) ?

Is there no way for CSS variables to represent the current value of another style declaration?


Solution

  • Actually, you can set a CSS custom property instead of setting directly the color property, and use it for color and background-color.

    /* Set global variable inside the :root scop */
    :root {
      --color-top: rgb(255,0,0);
    }
    
    div {
      float: left;
      width: 200px;
    }
    
    div div {
      float: none;
    }
    
    /* Set the local --color variable, according to your need */
    .top {
      --color: var(--color-top);
    }
    
    .middle {
      --color: rgb(255,227,0);
    }
    
    .bottom {
      --color: rgb(63,255,63);
    }
    
    .jp .bottom {
     --color: rgb(0,255,191);
    }
    
    .light {
      color: var(--color);
      text-align: center;
    }
    
    .light::before {
      content: '';
      display: block;
      margin: 6px auto 0;
      width: 45px;
      height: 45px;
      border-radius: 15px;
      background-color: var(--color);
    }
    <div class="uk">
    <h2>UK Traffic Lights</h2>
    <div class="top light">Red</div>
    <div class="middle light">Amber</div>
    <div class="bottom light">Green</div>
    </div>
    
    <div class="jp">
    <h2>JP Traffic Lights</h2>
    <div class="top light">Red</div>
    <div class="middle light">Amber</div>
    <div class="bottom light">Blue</div>
    </div>

    I do not really understand why you are not using background-color: currentColor, because it works well in your own example.