Search code examples
csscss-variables

How to set CSS variable to the value unset, "--unset-it: unset"?


I want to give a CSS variable the value unset, so I can use it for things like outline: unset. (I am aware that the "unset" in --unset-it: unset refers to the variable itself.)

Can it be done? I have made some test here:

const theDump = document.getElementById("dump");
const root = document.documentElement;
let checked = false;

document.getElementsByName("unset-it").forEach((elt) => {
  function displayIt(elt) {
    root.style.setProperty("--unset-it", elt.value);
    const propVal = getComputedStyle(root).getPropertyValue("--unset-it");
    theDump.textContent = `--unset-it: ${propVal};`;
  }
  if (!checked) {
    checked = true;
    elt.checked = true;
    elt.focus();
    displayIt(elt);
  }
  elt.addEventListener("click", evt => {
    const elt = evt.target;
    displayIt(elt);
  });
});
* {
  box-sizing: border-box;
}

#ex {
  background: yellow;
  padding: 0.5rem;
  margin: 1rem 0;
}

input[type=radio] {
  position: relative;
  width: 15rem;
  margin: 0;
  margin-left: 1rem;
  margin-bottom: 0.5rem;
}

input[type=radio]::after {
  content: attr(value);
  position: absolute;
  left: 0;
  top: 0;
}

#div1 {
  outline: var(--unset-it, 2px dotted red);
}
<input type="radio" name="unset-it" value='"unset"'>
<input type="radio" name="unset-it" value="'unset'">
<input type="radio" name="unset-it" value='unset'>
<input type="radio" name="unset-it" value='whatever'>
<input type="radio" name="unset-it" value='"whatever"'>
<input type="radio" name="unset-it" value='5px solid green'>
<input type="radio" name="unset-it" value='"5px solid green"'>
<input type="radio" name="unset-it" value="initial">

<div id="ex">
  <p id="div1">
    outline: var(--unset-it, 2px dotted red);
  </p>
  <p id="dump">Dump</p>
</div>


Solution

  • Like I did in this previous answer with inherit You need to make unset the fallback value and consider initial to activate it:

    * {
      box-sizing: border-box;
    }
    
    #ex {
      background: yellow;
      padding: 0.5rem;
      margin: 1rem 0;
    }
    
    
    #div1 {
      --unset-it: 2px dotted red;
      outline: var(--unset-it, unset);
    }
    <div id="ex">
      <p id="div1">
        outline: 2px dotted red;
      </p>
      <p id="div1" style="--unset-it:initial">
        outline: unset;
      </p>
    </div>

    The trick should work with any global value like unset, inherit, initial and revert


    Another idea is to consider invalid value at computed time. From the specification we can read:

    A declaration can be invalid at computed-value time if it contains a var() that references a custom property with its initial value, as explained above, or if it uses a valid custom property, but the property value, after substituting its var() functions, is invalid. When this happens, the computed value of the property is either the property’s inherited value or its initial value depending on whether the property is inherited or not, respectively, as if the property’s value had been specified as the unset keyword.

    * {
      box-sizing: border-box;
    }
    
    #ex {
      background: yellow;
      padding: 0.5rem;
      margin: 1rem 0;
    }
    
    
    #div1 {
      outline: var(--unset-it, 2px dotted red);
    }
    <div id="ex">
      <p id="div1">
        outline: 2px dotted red;
      </p>
      <p id="div1" style="--unset-it:'random-value-here'">
        outline: unset;
      </p>
    </div>

    You should pay attention when using this because it is closely related to the property where you will be using the CSS variable since the validity of the value depend on the property.

    Examples of value valid for some property and invalid for others:

    * {
      box-sizing: border-box;
    }
    
    #ex {
      background: yellow;
      padding: 0.5rem;
      margin: 1rem 0;
    }
    
    
    #div1 {
      outline: var(--unset-it, 2px dotted red); /*invalid here*/
    }
    #div1::before {
      content:var(--unset-it,"content"); /* valid here */
    }
    <div id="ex">
      <p id="div1" style="--unset-it:'random-value-here';">
        outline: unset;
      </p>
    </div>