Why Can't I Animate Custom Properties (Aka CSS Variables)

Why can't I animate custom properties (aka CSS variables)?

When this question was asked, it wasn't possible to animate custom properties, as @temani afif correctly pointed out -

since the UA has no way to interpret their contents

Since then, CSS Houdini have put together the CSS Properties and Values API specification

This specification extends [css-variables], allowing the registration
of properties that have a value type, an initial value, and a defined
inheritance behaviour, via two methods:

A JS API, the registerProperty() method

A CSS at-rule, the @property rule

So now that you can register your own custom properties - including the type of the custom property - animating the custom property becomes possible.

To register the custom property via CSS - use the @property rule

@property --o {
syntax: "<number>";
inherits: false;
initial-value: 0;
}

#one {
width: 50px;
height: 50px;
background-color: gold;
--o: 0;
animation: roll-o-1 2s infinite alternate ease-in-out both;
position: relative;
left: calc(var(--o) * 1px);
}

@keyframes roll-o-1 {
0% {
--o: 0;
}
50% {
--o: 50;
}
100% {
--o: 100;
}
}

#two {
width: 50px;
height: 50px;
background-color: silver;
animation: roll-o-2 2s infinite alternate ease-in-out both;
position: relative;
}

@keyframes roll-o-2 {
0% {
left: 0px;
}
50% {
left: 50px;
}
100% {
left: 100px;
}
}

@property --o {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
<div id="one"></div>
<br>
<div id="two"></div>

CSS animate custom properties/variables

This can be achieved by defining variables using (as of writing this, not well-supported) @property, which allows declaring types and that allows the browser to "understand", for example, that a certain property (variable) is a Number and then it can gradually animate/transition that variable.

Example Code:

@property --opacity {
syntax: '<number>'; /* <- defined as type number for the transition to work */
initial-value: 0;
inherits: false;
}

@keyframes fadeIn {
50% {--opacity: 1}
}

html {
animation: 2s fadeIn infinite;
background: rgba(0 0 0 / var(--opacity));
}

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>

Accessing a CSS custom property (aka CSS variable) through JavaScript

You can use document.body.style.setProperty('--name', value);:

var bodyStyles = window.getComputedStyle(document.body);
var fooBar = bodyStyles.getPropertyValue('--foo-bar'); //get

document.body.style.setProperty('--foo-bar', newValue);//set

More Information here.

Are CSS Custom Properties global across linked CSS documents?

In MDN:

Custom properties participate in the cascade: each of them can appear
several times, and the value of the variable will match the value
defined in the custom property decided by the cascading algorithm.

It works just like any other CSS properties. It should be declared in the ancestor of the target element. So usually it would be declared to the top-level element html or root:.

It does not matter whether CSS custom properties are declared in an external CSS file or the same file.

The following is a sample using two external CSS files. It works on Firefox, Safari and Chrome.

https://thatseeyou.github.io/css3-examples/basics/customproperty.html

variables.css :

:root {
--red: #f00;
--green: #0f0;
--blue: #00f;
}

style.css :

.red {
background-color: var(--red);
}
.green {
background-color: var(--green);
}
.blue {
background-color: var(--blue);
}

HTML :

<!DOCTYPE html>
<html lang="en">
<head>
<link href="customproperty/variables.css" rel="stylesheet">
<link href="customproperty/style.css" rel="stylesheet">
<style>
.module {
--red: #800;
--green: #080;
--blue: #008;
}
</style>
</head>
<body>
<div class="red">red</div>
<div class="green">green</div>
<div class="blue">blue</div>
<div class="module">
<div class="red">red in module</div>
<div class="green">green in module</div>
<div class="blue">blue in module</div>
<div>
</body>
</html>


Related Topics



Leave a reply



Submit