[SOLVED] Is it possible to render gradient animation transitions based on state?

I’m coding in React and I want one gradient transition to another gradient.

I’ve already done some Google-fu and the best I could come up with was using the pseudo-selector .class:before, setting the gradient I want to transition to on that, and setting the opacity to 0. You can see an example (not mine) here.

While the transition works if I use something like hover, I don’t know if it’s possible to make the transition render via state. Afaik you can’t write pseudo-selectors in html (or JSX for that matter).

Yes but depending on what you’re doing you’re likely going to want to look at React’s transition group (it’s now maintained as a separate package).

The issue you have is that elements in React tend to get completely rerendered (they get pulled completely in or out of the DOM), so you can’t rely on them existing, so CSS animations don’t generally work out of the box beyond simple stuff. When the state changes React is going to want to rerender your button, which will bork your animation. What the transition group does is add classes before an element changes and after an element changes (and at a lower level gives you callbacks is that match these) which you can hook into.

There are also a load of other good packages, For the most common use case, motion is v good

I find React pose to be really straightforward to use. Plus it uses the FLIP technique.

Thank you @DanCouper and @JM-Mendez for the help :slight_smile:! I actually solved this not too long ago but forgot to share my solution. I ended up using react-transition-group to apply the animations when the elements entered and left the DOM.

Here is what I did:

        {/* Use two separate backgrounds to transition color 
            via opacity because gradients are not animatable. */}
        <div className="PomodoroBackground" />
        {/* CSSTransitionGroup applies fade to mounting and unmounting elements. */}
        <CSSTransitionGroup
          transitionName="gradientTransition"
          transitionEnterTimeout={1000}
          transitionLeaveTimeout={500}
        >
          {timerType == "Rest" ? (
            <div className="RestBackground" key="RestBackground" />
          ) : (
            ""
          )}
        </CSSTransitionGroup>
.PomodoroBackground {
  margin: auto;
  background: linear-gradient(#FAC368, #EB6C52);
  height: 100vh;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

.RestBackground {
  margin: auto;
  background: linear-gradient(#27AAC5, #2E58B8);
  height: 100vh;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

Because gradients are not animatable, I have two divs just for two different backgrounds. One div always remains, while the other is either is added or removed from the DOM based on state. The <CSSTransitionGroup> element from react-transition-group applies the fade effects.

Here it is in action:

react transition group animations

Cheers :+1:!

1 Like

Ooh, that it a very nice looking thing as well.

1 Like