[Vuejs]-Can't stop text gradient animation from resetting when complete

0👍

Basically, animation-fill-mode: forwards would retain the style values that are set by the last keyframe. But when you use the vue Transition component, the class titleAnimation-enter-active is:

Applied during the entire entering phase. Added before the element is inserted, removed when the transition/animation finishes

See the docs

When the class is removed, all CSS properties (including animation) will be removed from the element. So your style will not be applied.

Solution

  • Add all desired styles to your element class (.title), NOT the transition active class
  • Add animation styles to transition classes

Solution 1: Use CSS transition

const {
  createApp,
  ref
} = Vue

createApp({
  setup() {
    const showHero = ref(false)
    return {
      showHero
    }
  }
}).mount('#app')
.hero {
  padding: 3em 5em;
  border: solid 1px black;
  text-align: center;
  transition: 3s transform;
  will-change: transform;
}

h1 {
  color: green;
  font-size: 5em;
}


/* for entering animation */

.hero-enter-from {
  transform: scale(0);
}


/* for leaving animation */

.hero-leave-to {
  transform: scale(0);
}
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

<div id="app">
  <button @click="showHero = !showHero">Toggle</button>
  <Transition name="hero">
    <div class="hero" v-if="showHero">
      <h1>I'm growing</h1>
    </div>
  </Transition>
</div>

Solution 2: Use CSS animation

const {
  createApp,
  ref
} = Vue

createApp({
  setup() {
    const showHero = ref(false)
    return {
      showHero
    }
  }
}).mount('#app')
.hero {
  padding: 3em 5em;
  border: solid 1px black;
  text-align: center;
  will-change: transform;
}

h1 {
  color: green;
  font-size: 5em;
}


/* for entering animation */

.hero-enter-active {
  animation: upScale 3s;
}


/* for leaving animation */

.hero-leave-active {
  animation: downScale 3s;
}

@keyframes upScale {
  from {
    transform: scale(0);
  }
  to {
    transform: scale(1);
  }
}

@keyframes downScale {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(0);
  }
}
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app">
  <button @click="showHero = !showHero">Toggle</button>
  <Transition name="hero">
    <div class="hero" v-if="showHero">
      <h1>I'm growing</h1>
    </div>
  </Transition>
</div>

Leave a comment