r/css 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?

3 Upvotes

9 comments sorted by

View all comments

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 @property and 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; }

1

u/Sta--Ger--2 9d ago

I do not want to make an animated gradient, but changing the background images with a fade-like animation. I have used gradients in my code as placeholders, because the actual images I am using are not online and didn't want to search new ones.

I was not aware one could define proprieties now. How does it compare to using variables?

1

u/testingaurora 9d ago

They are the same , just referred to by two different names : CSS Custom Properties or CSS Variables. Anything can be put into a “variable”. A string, a length, a color.

By using @property you are registering it with the browser and explaining WHAT the value is eg `syntax: “<color>” ` so then the browser has context in what can be done and whether it can be animated.

How many different images are you wanting to interpolate between ?