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.
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>
CSS custom property change on inherited (color) value doesn't work
The property is properly redefined, but until you don't set the color
property then the element .bar
inherits the color from its parent, and in the scope of the parent that color is red.
:root { --color: red; --color2: blue;}
.foo { color: var(--color);}
.bar { --color: var(--color2); color: var(--color);}
<div class="foo"> foo <div class="bar"> bar </div></div>
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>
Can we inherit a custom variable defined in a class in another class?
From the specification:
Custom properties are ordinary properties, so they can be declared on any element, are resolved with the normal inheritance and cascade rules, can be made conditional with @media and other conditional rules, can be used in HTML’s style attribute, can be read or set using the CSSOM, etc.
And also:
Inherited: yes
So it's not about the inheritance from another class but the usual inheritance from a parent (or ancestor) element exactly like any inherited property.
In your case penguin-top
is a child of penguin
so it will inherit its custom properties.
Worth to note that :root
is the html
element which is the ancestor of all the elements that's why all them will logically inherit custom property defined inside :root
CSS Variables inheritance and fallback
As JoseAPL has stated, the reason var()
expressions accept a fallback argument instead of defaulting to inheritance is simply because while custom properties do inherit, not all of the standard properties you will use them with do.
On the other hand, if you're asking why a var()
expression doesn't default to the next best-cascaded value, that's because by the time the var()
expression is evaluated, there are no other values to fall back to, because every other declaration in the cascade has been erased. See section 3.1, which defines the term invalid at computed-value time:
Note: The invalid at computed-value time concept exists because variables can’t "fail early" like other syntax errors can, so by the time the user agent realizes a property value is invalid, it’s already thrown away the other cascaded values.
Having said that, you can provide a custom property as a fallback value (as long as it's not the same one, for the same reason explained above) — that custom property just needs to appear in its own var()
expression, since the fallback value is, well, a declaration value, not a property name.
So the result is a var()
nested inside another var()
:
body span {
--color3: green;
color: var(--color3);
color: yellow;
color: var(--color4, var(--color3));
}
:root { --color1: red;}
body { color: var(--color1);}
body p { color: var(--color2); --color2: blue;}
body span { --color3: green; color: var(--color3); color: yellow; color: var(--color4, var(--color3));}
<body> Text 1 <p> Text 2 </p> <span> Text 3 </span></body>
CSS custom properties as fallback value of another one instead of fixed (predefined) value
Custom properties or CSS variables are only accessed using the var() function.
Use var(--my-var, var(--my-background, pink))
.
For more information, checkout out Custom property fallback values.
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 Variables (custom properties) in Pseudo-element content Property
Edit for clarity: CSS custom properties with integer values can be displayed in a pseudo-element's content
property via a CSS counter.
div {
--variable: 123;
}
span:after {
counter-reset: variable var(--variable);
content: counter(variable);
}
<div>The variable is <span></span>.</div>
Related Topics
How to Float Paragraph Next to Image Without Wrapping the Image
Is There a Trick to Show Arial Black in Firefox
CSS Resize Property - Change Resize Icon Properties
Make a Pause During Infinite CSS3 Animation
CSS Border Shorthand When Each Border Has a Different Width
Javafx CSS Button with Image - How to Define the Size of the Image
How to Create Hollow Triangle in CSS
In CSS Grid Layout, Do We Count the Span Even Starting on Implicit Grid Lines
How to Create Circle with Four Quarters
Javafx Text Styling for Dynamic Objects
Bootstrap Collapse Menu Disappears When Resizing Screen
Z-Index When Using ::After Under Element
Sass Mixin Error for Ie Specific Filters Like -Ms-Filter
Use of "Text-Decoration-Color" Is Not Working
Can You Make Ie 9 (Or Earlier) Lay Out Table Elements as If They Were Regular Display:Block Elements