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>
To register the property via javascript - use the CSS.registerProperty()
method:
CSS.registerProperty({
name: "--o",
syntax: "<number>",
initialValue: 0,
inherits: "false"
});
CSS.registerProperty({
name: "--o",
syntax: "<number>",
initialValue: 0,
inherits: "false"
});
#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;
}
}
<div id="one"></div>
<br>
<div id="two"></div>
NB
Browser support is currently limited to chrome (v78+ for registerProperty()
, v85+ for @property
) edge and opera