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:
- 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.- 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,- 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.- 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>
How do I set a value of `inherit` to a CSS custom property?
I did some thinking and this solution just hit me. I can use custom properties in conjunction with preprocessor mixins.
<style type="text/less">
// NOTE: not syntactically valid CSS!
.mx-border(@arg) {
border: @arg;
}
figure {
.mx-border(1px solid red);
--foobar: 1px solid green;
}
figure > figcaption {
.mx-border(var(--foobar));
}
figure > figcaption:hover {
.mx-border(inherit);
}
</style>
<figure>this figure has a red border
<figcaption>this figcaption has a green border
because it inherits --foobar</figcaption>
</figure>
<!-- on hover -->
<figure>this figure has a red border
<figcaption>This figcaption
has a red border because the mixin
sets the `border` property to `inherit`.</figcaption>
</figure>
This way, I can encapsulate all the dependent styles into the .mx-border()
mixin. Doing this doesn’t take advantage of CSS custom properties, but it does alleviate the hassle of writing everything a second time for the :hover
.
Essentially it is the same as writing border: inherit;
, with the added ability of putting more styles into the mixin and not having to duplicate them.
Why display property set to inherit with CSS variable doesn't work?
In such situation, inherit
is used as a value for the custom property and will not be evaluted to the inherit
value using var()
.
Here is a basic example to understand the issue:
.box { --c:inherit; color:var(--c,red);}
<div> <div class="box">I am a text</div></div><div style="--c:blue"> <div class="box">I am a text</div></div>
how to reset a CSS variable (aka custom properties) and use the fallback one?
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>
css variable - default value on var not getting passed
Custom properties inherit.
From the spec:
Custom properties are ordinary properties, so they can be declared on
any element, are resolved with the normal inheritance and cascade
rules, ...
This means that if no value is set for a custom property on a given element, the value of its parent is used.
In this case, the parent element defines the custom property: --span
:
<div class="item" style="--span: 7">
So the value of the --span property will be 7 on all the children - unless a different value is explicitly defined on a child.
Now the difference between the two versions of the code is clear.
In the commented version, var(--span, 1)
in the .item class evaluates to 7 due to inheritance
Since there are only 2 columns in the grid, each item spans the full grid width
In the uncommented version (with --span: 1
; defined in the .item class), var(--span, 1)
in the .item class evaluates to 1 - because it is explicitly defined on the child.
NB
Fallback values are only used as the substitution value when a given custom property is invalid / not defined
In this case, the second item in the outer grid defines the --span custom property with value 7 and it is available to all its child elements.
How to set CSS variable to the value unset, --unset-it: unset ?
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>
Related Topics
Automatically Resize Images with Browser Size Using CSS
Font-Size Issues Comparing Chrome and Firefox
Angular 2: How to Style Host Element of the Component
Defining Variable Variables Using Less CSS
How to Put an Image in Div with CSS
What Has Bigger Priority: Opacity or Z-Index in Browsers
Add a CSS Class to Single Code Chunks in Rmarkdown
Have a Variable in Images Path in SASS
Css Selector to Select First Element of a Given Class
Svg in Img Element Proportions Not Respected in IE9
What Are the Differences Between Flex-Grow and Width
How to Override the Properties of a CSS Class Using Another CSS Class
@Font-Face Src: Local - How to Use the Local Font If the User Already Has It
How Can One Import Only Variables and Mixins from SASS Stylesheets