Custom CSS Properties, Why Not

using css custom properties variables not working

You did everything right, just keep the variables in (put variable here)

element {
--main-bg-color: brown;
}
body {
background-color: var(--main-bg-color);
}

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>

Is there a difference between CSS custom properties and CSS variables?

A CSS Custom Property is the same thing as a CSS Variable. But that seems to come of some clumsy naming.

They weren't wrong to title the page: Using CSS custom properties (variables)

However a CSS Variable is not a variable in the traditional sense, as there is no way to define it so that it is globally scoped like in a programming language, or CSS Preprocessor (LESS/Sass).

Even a root scoped custom property/variable is not global. Changing the value of a property in a child will not change the value above or for siblings of that scope. If someone is expecting to be global, it may cause confusion and I suspect that's what Mozilla's writers are trying to point out.

if you look at

w3.org's CSS Custom Properties for Cascading Variables

This module introduces a family of custom author-defined properties known collectively as custom properties

Custom properties are definitions that can be referenced using var(--my-custom-prop). Like a variable!

quote continued...

as one only has to change the value once, in the custom property, and the change will propagate to all uses of that variable automatically.

Awkward... The above statement is not true exactly. It seems Mozilla Developer Network documentation is trying clarify that idea so that it's less confusing. Repeating the original quote:

Keep in mind that these are custom properties, not actual CSS variables. The value is computed where it is needed, not stored for use in other rules. For instance, you cannot set a property for an element and expect to retrieve it in a sibling's descendant's rule. The property is only set for the matching selector and its descendants, like any normal CSS.

They're pointing out it's not a variable in the traditional sense of a programming language. But that it is computed just like styles, adhering to the general cascade/scoping rules of CSS.

Thus var(--my-custom-prop) could resolve to very different things based on where it is declared, and that declarations don't propagate out to a higher scope.

Here's a codepen to mess around with if you'd like to try it out.

So think of CSS Custom Property the same as CSS Variable but be sure to remember that values cascade, and there's no global scope.

When using CSS Variables (CSS Custom Properties) why is the setting syntax and the getting syntax different?

Having been using CSS Custom Properties since late 2017, I've finally understood properly what they really are and why the var() function is necessary...

They are not (as they so often appear to be) variables intended to directly represent CSS values.

CSS Custom Properties are exactly what they say they are - they are new CSS properties which have not (yet) been assigned values.


In CSS, an example of something which really does approximate a variable representing a value is currentColor.

We see currentColor representing a value, here:

.my-div {
border: 1px dashed currentColor;
}

But CSS Custom Properties are not CSS variables which stand in for values like currentColor, .

Instead, CSS Custom Properties are newly invented, named, null-value-properties...

... and those newly-invented, named, null-value-properties are completely re-usable. Just like width, height, color etc. they may have values set and reset in different contexts.

E.g.

/* My custom property is --my-custom-width but I want this
property to hold different values in different contexts */

.left-two-thirds-of-page {
--my-custom-width: 120px;
}

.right-third-of-page {
--my-custom-width: 60px;
}

.my-div {
width: var(--my-custom-width);
}

That's why the var() function is necessary - it's not delivering "the custom property" - it's extracting the value that custom property is currently holding and then delivering that value.



Further Thoughts:

In hindsight, I wonder if the whole name-value relationship wouldn't have been a little clearer if CSS Custom Properties had been called:

CSS Custom Property Names

and the corresponding function had been called:

value()

so the syntax would have been written and read out as:

value(--my-custom-property-name)

By extension we could use the value() function (or var() function) not just on custom properties but on any property.

For instance:

width: value(height);

Angular component custom style from parents

Finally I found how to solve this:

Child component

.cmp-class {
color: var(--custom-color, red);
}
<div class="cmp-class"><p>Hello</p></div>


Related Topics



Leave a reply



Submit