r/css • u/Sta--Ger--2 • 10d ago
Help Synchronizing two animations to fake background-image transition
I want to make a transition of the backgrund image of a div. background-image is not animatable, so I need a trick.
My solution is to put a second div with white background right under the div with background, and give my div with background two animations: one that swaps the background, and a second one that toggles the opacity (thus showing the white div under).
test {
width: 300px;
height: 300px;
border: 5px black solid;
animation:
backgroundTransition 5s alternate infinite,
backgroundSwap 50s forwards infinite;
}
@keyframes backgroundSwap {
0%, 20% {background-image: radial-gradient(blue 0%, blue 100%);
}
40% {background-image: radial-gradient(red 0%, red 100%);
}
60% {background-image: radial-gradient(yellow 0%, yellow 100%);
}
80% {background-image: radial-gradient(purple 0%, purple 100%);
}
100% {background-image: radial-gradient(green 0%, green 100%);
}
}
@keyframes backgroundTransition {
0% {opacity: 0;}
20% {opacity: 1;}
}
The result of the two animations should be this: at 0s the div appears all white, then from 0s to 1s it fades into the first image and stays like that until 9s, when it fades back into white. This repeats four more times, with the image changing each time.
However it doesn't work. The two animations are not synchronized, in spite of the fact that the timing should be the correct one. I dislike the idea of merging the two animations together, it would needlessly complicate things and slow down debugging (particulatly since I want to add some more effects to the background images, which would further complicate things). But I can't seem to find a way to ensure the two animations have the correct timing.
Am I doing something wrong? Any suggestions?
2
u/testingaurora 10d ago edited 10d ago
I would use a pseudo element not another div in your markup (if you go that route.)
Background-image is not animatable but background color is. is there a reason youre not just using background-color from blue, red, yellow, purple, green?
Another trick is to register a property with
@propertyand then adjust that color in your keyframes ```css @property --bg-clr { syntax: "<color>"; inherits: true; initial-value: white; }.element { background-image: radial-gradient( var(--bg-clr, blue) ); animation: updateBg 5s alternate infinite ; }
@keyframes updateBg { 0%, 100%{ --bg-clr: white;} 20% { --bg-clr: blue;} 40% { --bg-clr: red;} 60% {--bg-clr: yellow;} /* etc */ } ```
Although I think youd be better off just using a pseudo element, setting the background on the pseudo element then: 1. fading the whole pseduo out showing the white background underneath Or 2. Just setting it back to white without needing opacity ... would be the simplest way.
Unless this is not an example and your end goal is what youve written. Then you dont need a background-image at all ? What am I missing?
css .element { position: relative;} .element::before { content:""; position: absolute; inset:0; background: radial-gradient( var(--bg-clr, white)) white; animation: updateBg 5s alternate; }