How to store inherit value inside a CSS variable (aka custom property)?

In such case, we can consider the fallback value of a CSS variable. Like explained in the specification we can write something like this:

background:var(--color,inherit)

By doing this, we tell our property (background) to use inherit in case --color is not defined.

This may solve the issue but in our case it won’t be enough since --color is always defined at :root level and will get inherited1 by the pseudo element thus we will never use the fallback value.

To fix this we can consider the initial value in order to undefine our custom property and force the use of the fallback value. As described in the specification:

The initial value of a custom property is an empty value; that is, nothing at all. This initial value has a special interaction with the var() notation, which is explained in the section defining var().

and

To substitute a var() in a property’s value:

  1. If the custom property named by the first argument to the var()
    function is animation-tainted, and the var() function is being used in
    the animation property or one of its longhands, treat the custom
    property as having its initial value for the rest of this algorithm.
  2. If the value of the custom property named by the first argument to the
    var() function is anything but the initial value, replace the var()
    function by the value of the corresponding custom property. Otherwise,
  3. if the var() function has a fallback value as its second argument,
    replace the var() function by the fallback value. If there are any
    var() references in the fallback, substitute them as well.
  4. Otherwise, the property containing the var() function is invalid at
    computed-value time

Our code will then look like this:

:root {
  --color:rgba(25,25,25,0.5); /*defined as the default value*/
}

.box {
  width:50px;
  height:50px;
  display:inline-block;
  margin-right:30px;
  border-radius:50%;
  position:relative;
}
.red {background:rgba(255,0,0,0.5);}
.blue {background:rgba(0,0,255,0.5);}

.box:before{
  content:"";
  position:absolute;
  top:0;left:0;right:0;bottom:0;
  border-radius:50%;
  transform:translateX(30px);
  background:var(--color,inherit);
  filter:invert(1);
}
<div class="box red" style="--color:initial;">
</div>
<div class="box blue" style="--color:initial;">
</div>

<div class="box" style="background:grey;--color:initial;">
</div>

We simply need to set initial to the custom property in order to force the inherit to be used as a value within background.


The usage of initial can also be useful in order to stop the propagation of CSS variable at a particular level since by default it’s inherited by all the elements.

Here is an example:

:root {
  --color: blue;
}
.container div{
  border:5px solid var(--color,red);
  padding:5px;
}
.stop {
  --color:initial;
}
.green {
  --color:green;
}
<div class="container">
  <div> 
    <div>
      <div class="stop"> <!-- we stop at this level -->
        <div>
        </div>
      </div>
    </div>
  </div>
</div>

<div class="container stop"> <!-- we stop at this level -->
  <div> 
    <div>
      <div class="green">  <!-- we redefine at this level -->
        <div>
        </div>
      </div>
    </div>
  </div>
</div>

1: it’s about the inheritance of the custom property and not the background property

Leave a Comment