Can I use a custom property with fallback to define part of a custom property
CSS variables don't work in the way that you are trying to use them. Variables that are defined with other variables only take variables on the same level or levels above them.
A nice "hack" that I found was, instead of using the :root
selector, use the universal selector *
to define the varibales on all levels. That way, since you define the color variables on the same level, changing the opacity variable works. Keep in mind that this might cause some unwanted results, and if you want to consider other solutions, these might help you:
CSS scoped custom property ignored when used to calculate variable in outer scope
Overriding :root CSS variables from inner scopes
* {
--opacity: 50;
--clr-900: hsla(36, 83%, 0%, var(--opacity, 1));
--clr-700: hsla(36, 83%, 30%, var(--opacity, 1));
--clr-300: hsla(36, 83%, 70%, var(--opacity, 1));
--clr-200: hsla(36, 83%, 85%, var(--opacity, 1));
--clr-100: hsla(36, 83%, 100%, var(--opacity, 1));
}
.test1 {
background-color: var(--clr-900);
}
.test2 {
--opacity: 0.65;
background-color: var(--clr-900);
}
<p class="test1">hello world</p>
<p class="test2">hello world</p>
Explain this CSS custom properties behavior
--hover-color
resolves to the --color
value of the scope in which it exists, meaning it will compute the value detected at that time. This is to avoid dependency cycles. You can read about these cycles in the specification document.
Custom properties are left almost entirely unevaluated, except that they allow and evaluate the
var()
function in their value. This can create cyclic dependencies where a custom property uses avar()
referring to itself, or two or more custom properties each attempt to refer to each other.
To prevent this, you would want to expand a bit, and do the following:
:root {
--color: red;
--hover-color: var(--color);
}
div {
--color: green;
--hover-color: var(--color); /* Added this here */
background: var(--color);
}
div:hover {
background: var(--hover-color);
}
<div>
I am green on hover, as expected.
</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 does the Cascade for CSS Custom Properties Not Work?
In your script, you're setting the custom properties on the body
element. However, in your stylesheet, your custom properties are all (as usual) specified for :root
, the html
element. So the value of --global-primary-colour-hue
is unchanged for :root
, and the value of --global-primary-colour
in turn remains unchanged. This unchanged value then gets inherited by body
and .box
— the new value of --global-primary-colour-hue
ends up never getting used.
Setting the property for document.documentElement
in your script, or changing the CSS rule to target body
instead, allows your code to work correctly without needing that last line:
var element = document.getElementById("hue-range");element.onchange = function(){ document.documentElement.style.setProperty( "--global-primary-colour-hue", this.value);}
:root { --global-primary-colour-hue: 211; --global-primary-colour-saturation: 100%; --global-primary-colour-lightness: 50%; --global-primary-colour-opacity: 1; --global-primary-colour: hsla( var(--global-primary-colour-hue), var(--global-primary-colour-saturation), var(--global-primary-colour-lightness), var(--global-primary-colour-opacity));}
.box { background-color: var(--global-primary-colour); height: 100px; width: 100px;}
<input id="hue-range" value="0" type="range" min="0" max="360">
<div class="box"></div>
CSS variables: input:focus doesn't set variable
The new CSS pseudo-class :focus-within
would be your best shot to achieve this.
The :focus-within pseudo-class matches elements that either match :focus themselfves or that have child which match :focus.
:root { --textbox-box-shadow: none;}
.example3 { display: block; border: 1px solid red; padding: 10px; box-shadow: var(--textbox-box-shadow);}
.example3:focus-within { --textbox-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px red;}
<div class="example3"> Enter your name : <input class="ip"></div>
Related Topics
How to Place Two Divs Next to Each Other
Floating Elements Within a Div, Floats Outside of Div. Why
How to Get Div Height to Auto-Adjust to Background Size
How to Make a Child Div'S Width Wider Than the Parent Div Using Css
Child Inside Parent With Min-Height: 100% Not Inheriting Height
How to Make a Floated Div 100% Height of Its Parent
Canvas Has White Space At the Bottom and Scrolls Too Far
Ipad Safari Scrolling Causes HTML Elements to Disappear and Reappear With a Delay
Does Height and Width Not Apply to Span
How to Apply a CSS Style on Html5 Datalist Options
Center a 'Div' Vertically in a % Height 'Div'
Disable Webkit'S Spin Buttons on Input Type="Number"
How to Make Fixed Header Table Inside Scrollable Div
In CSS Flexbox, Why Are There No "Justify-Items" and "Justify-Self" Properties
What Methods of 'Clearfix' How to Use
What Does a Space Mean in a CSS Selector? I.E. Difference Between .Classa.Classb and .Classa .Classb