Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to reset a CSS variable (aka custom properties) and use the fallback one?

I am trying to have CSS variables for box model properties. I want to support both setting a value for all sides as well as individual sides. I want to have default values, but be override-able either way. I tries using fallback values, but with little success.

Something like:

:root {
  --border-width-top: 0;
  --border-width-right: 0;
  --border-width-bottom: 0;
  --border-width-left: 0;
  --border-width: 0;
}
div {
  border-color: red;
  border-style: solid;
  border-width: var(--border-width, var(--border-width-top) var(--border-width-right) var(--border-width-bottom) var(--border-width-left));
}


div {
  --border-width-top: 10px;
}

This will not work as if border-width has a default value then it will always take precedence over the fallback values. Not sure there is a way to do this currently, but I feel so close to finding a solution.

Here is a stackblitz I am playing with: stackblitz

like image 264
masimplo Avatar asked Apr 10 '19 14:04

masimplo


People also ask

How do you unset a variable in CSS?

To unset the value of an element, unset keyword is used. The unset CSS keyword resets a property of an element to its inherited value if the property naturally inherits from its parent, or to its initial value if it does not inherit.

Can CSS variables be changed?

CSS variables have access to the DOM, which means that you can change them with JavaScript.

How do you initialize a variable in CSS?

The initialization of the CSS variable is done by prefixing “–” to the variable name. For example, the following syntax initializes the variable “my_font” to 20px. font-size: var(--my_font, 20px); Fallback values work differently in different aspects.


1 Answers

You can unset the value using initial to use the fallback one:

:root {
  --border-width-top: 2px;
  --border-width-right: 2px;
  --border-width-bottom: 2px;
  --border-width-left: 2px;
  --border-width: 0;
}
div {
  margin:5px;
  border-color: red;
  border-style: solid;
  border-width: var(--border-width, var(--border-width-top) var(--border-width-right) var(--border-width-bottom) var(--border-width-left));
}


div.box {
  --border-width:initial;
  --border-width-top: 10px;
}
<div>some content</div>
<div class="box">some content</div>

from the 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
like image 188
Temani Afif Avatar answered Oct 08 '22 09:10

Temani Afif