You can use this neat trick!
.element {
animation: move-y 1s;
background-position: var(--bgX) var(--bgY);
}
@keyframes move-y {
0% {
--bgY: 0;
}
1% {
--bgY: 1px;
}
2% {
--bgY: 2px;
}
3% {
--bgY: 3px;
}
4% {
--bgY: 4px;
}
5% {
--bgY: 5px;
}
6% {
--bgY: 6px;
}
7% {
--bgY: 7px;
}
8% {
--bgY: 8px;
}
9% {
--bgY: 9px;
}
10% {
--bgY: 10px;
}
11% {
--bgY: 11px;
}
12% {
--bgY: 12px;
}
13% {
--bgY: 13px;
}
14% {
--bgY: 14px;
}
15% {
--bgY: 15px;
}
16% {
--bgY: 16px;
}
17% {
--bgY: 17px;
}
18% {
--bgY: 18px;
}
19% {
--bgY: 19px;
}
20% {
--bgY: 20px;
}
21% {
--bgY: 21px;
}
22% {
--bgY: 22px;
}
23% {
--bgY: 23px;
}
24% {
--bgY: 24px;
}
25% {
--bgY: 25px;
}
26% {
--bgY: 26px;
}
27% {
--bgY: 27px;
}
28% {
--bgY: 28px;
}
29% {
--bgY: 29px;
}
30% {
--bgY: 30px;
}
31% {
--bgY: 31px;
}
32% {
--bgY: 32px;
}
33% {
--bgY: 33px;
}
34% {
--bgY: 34px;
}
35% {
--bgY: 35px;
}
36% {
--bgY: 36px;
}
37% {
--bgY: 37px;
}
38% {
--bgY: 38px;
}
39% {
--bgY: 39px;
}
40% {
--bgY: 40px;
}
41% {
--bgY: 41px;
}
42% {
--bgY: 42px;
}
43% {
--bgY: 43px;
}
44% {
--bgY: 44px;
}
45% {
--bgY: 45px;
}
46% {
--bgY: 46px;
}
47% {
--bgY: 47px;
}
48% {
--bgY: 48px;
}
49% {
--bgY: 49px;
}
50% {
--bgY: 50px;
}
51% {
--bgY: 51px;
}
52% {
--bgY: 52px;
}
53% {
--bgY: 53px;
}
54% {
--bgY: 54px;
}
55% {
--bgY: 55px;
}
56% {
--bgY: 56px;
}
57% {
--bgY: 57px;
}
58% {
--bgY: 58px;
}
59% {
--bgY: 59px;
}
60% {
--bgY: 60px;
}
61% {
--bgY: 61px;
}
62% {
--bgY: 62px;
}
63% {
--bgY: 63px;
}
64% {
--bgY: 64px;
}
65% {
--bgY: 65px;
}
66% {
--bgY: 66px;
}
67% {
--bgY: 67px;
}
68% {
--bgY: 68px;
}
69% {
--bgY: 69px;
}
70% {
--bgY: 70px;
}
71% {
--bgY: 71px;
}
72% {
--bgY: 72px;
}
73% {
--bgY: 73px;
}
74% {
--bgY: 74px;
}
75% {
--bgY: 75px;
}
76% {
--bgY: 76px;
}
77% {
--bgY: 77px;
}
78% {
--bgY: 78px;
}
79% {
--bgY: 79px;
}
80% {
--bgY: 80px;
}
81% {
--bgY: 81px;
}
82% {
--bgY: 82px;
}
83% {
--bgY: 83px;
}
84% {
--bgY: 84px;
}
85% {
--bgY: 85px;
}
86% {
--bgY: 86px;
}
87% {
--bgY: 87px;
}
88% {
--bgY: 88px;
}
89% {
--bgY: 89px;
}
90% {
--bgY: 90px;
}
91% {
--bgY: 91px;
}
92% {
--bgY: 92px;
}
93% {
--bgY: 93px;
}
94% {
--bgY: 94px;
}
95% {
--bgY: 95px;
}
96% {
--bgY: 96px;
}
97% {
--bgY: 97px;
}
98% {
--bgY: 98px;
}
99% {
--bgY: 99px;
}
100% {
--bgY: 100px;
}
}
The reason that this works is that the browser doesn't actually know how to move from "0" to "100px". Because these values aren't real numbers. They're strings! So, it makes sense to guide the browser in every step and tell it what to do.
Although there are two downsides to this. The first one obviously is that its big. I personally wouldn't mind that. what I would mind is that you have to calculate every step if it isn't as "simple" as the one I showed you. Let me explain:
It is "simple" if the difference between start and end points is 100 or something relatable. Which was the case in our example.
And it is not "simple" if otherwise, which causes something like this:
...
0% {
--bgY: 0;
}
1% {
--bgY: 0.3px;
}
2% {
--bgY: 0.6px;
}
...
With Everything said, this isn't something that a custom string generator wouldn't pull off. So, I would consider this the best way to change CSS vars with animation.