drake035
drake035

Reputation: 2897

Vue transition works for "enter" state but not for "leave" state

I have a modal rendered on top of a semi-transparent backdrop. Both elements have a v-if controlled by the same variable.

Although the enter transition animation works fine, the `leave`` transition animation is ignored (it should fade out smoothly, instead it disappears instantly). Why?

Codepen

Markup:

<div id="app">
  <button @click="showModal = !showModal">Toggle Modal</button>
  
  <div v-if="showModal" class="modalBackdrop">
    <transition name="content" appear>
      <div v-if="showModal" class="modalContent">
        Modal
      </div>
    </transition>
  </div>
</div>

CSS:

.content-enter-active {
  animation: slide-up .75s;
}

.content-leave-active {
  animation: fade-out .75s;
}

@keyframes slide-up {
  0% {
    transform: translateY(100%);
  }
  100% {
    transform: translateY(0);
  }
}

@keyframes fade-out {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

Upvotes: 2

Views: 1898

Answers (2)

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

It seems that the div with modalBackdrop class is disappearing before the nested div with class modalContent does its transition, so try to wrap modal Backdrop by a transition component with name backdrop which also takes the fade-out animation :

.backdrop-leave-active,.content-leave-active { /*.backdrop-leave-active is sufficient since the parent opacity is applied on children*/
  animation: fade-out .75s;
}

template :

<div id="app">
  <button @click="showModal = !showModal">Toggle Modal</button>
  <transition name="backdrop" appear>
    <div v-if="showModal" class="modalBackdrop">
      <transition name="content" appear>
        <div v-if="showModal" class="modalContent">
          Modal
        </div>
      </transition>
    </div>
  </transition>
</div>

DEMO

Upvotes: 1

Igor Moraru
Igor Moraru

Reputation: 7739

When showModal is false, the transition element is destroyed immediately. If the only reason you use v-if="showModal" in transition parent is to disable modalBackdrop, then you can assign this class dynamically.

This is working as expected:

  <div :class="{ modalBackdrop: showModal }">
    <transition name="content" appear>
      <div v-if="showModal" class="modalContent">
        Modal
      </div>
    </transition>
  </div>

Upvotes: 1

Related Questions