0

I'm trying to add an animation to this modal component that slides up from the bottom when the user clicks the button. The background blur display correctly on enter but the modal doesn't animate at all. I want it to slide in and when the model is closed I want it to slide back down.

What would be the best way to achieve this?

<template>
  <div>
    <a @click.prevent="toggle()">
      <slot name="button"></slot>
    </a>
    <div v-if="show" class="bg bg-transition fixed overflow-y-scroll top-0 left-0 flex flex-col items-center justify-center h-screen w-screen bg-opacity-25 bg-gray-400" style="backdrop-filter: blur(15px);">
      <transition mode="out-in" name="slideup">
        <div v-if="show" class="absolute top-0 right-0 left-0 bg-white rounded-tl-4xl rounded-tr-4xl w-full p-6 pb-0" style="margin-top:176px">
          <span class="flex items-center justify-center w-8 h-8 rounded-full bg-white text-gray-800 shadow" @click.prevent="toggle()">
            <svg
                class="fill-current w-full"
                xmlns="http://www.w3.org/2000/svg"
                width="24"
                height="24"
                viewBox="0 0 24 24"
              >
                <path
                  d="M19,6.41,17.59,5,12,10.59,6.41,5,5,6.41,10.59,12,5,17.59,6.41,19,12,13.41,17.59,19,19,17.59,13.41,12Z"
                />
                <path d="M0,0H24V24H0Z" fill="none" />
              </svg>
          </span>
          <div class="flex flex-col divide-y divide-gray-600">
            <div>
              <h1 class="heading mt-6">Placeholder Heading <br>R000pm</h1>
              <div class="mt-12 divide-y divide-gray-600">
                <div class="pb-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
              </div>
            </div>
            <div class="pt-20">
              <h1 class="heading">Placeholder Heading</h1>
              <div class="mt-8 divide-y divide-gray-800">
                <div class="pb-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
                <div class="py-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                  <div class="flex items-center justify-between mt-5">
                    <p class="font-semibold text-gray-1000 leading-none">Amount Limit Placeholder</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                  <div class="flex items-center justify-between mt-1">
                    <p class="font-semibold text-gray-1000 leading-none">Placeholder limit</p>
                    <p class="font-bold text-gray-1000 leading-none">R000,00</p>
                  </div>
                </div>
              </div>
            </div>
            <div class="pt-20 pb-10">
              <h1 class="heading">What you<br> should know</h1>
              <div class="mt-8 divide-y divide-gray-800">
                <div class="pb-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                </div>
                <div class="pt-8">
                  <h4 class="subheading">Placeholder Subheading</h4>
                  <p class="par mt-3">Placeholder Paragraph</p>
                </div>
              </div>
            </div>
          </div>
          <button class="text-lg font-semibold text-white px-5 py-2 mb-12 bg-orange-100 rounded-full focus:outline-none">Placeholder Button</button>
        </div>
      </transition>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.slideup-enter-active {
  animation: flyover 2s ease-in;
}

.slideup-leave-active {
  animation: flyover-reverse 2s ease-out;
}

.heading {
  @apply text-3xl text-gray-1000 leading-none;
  line-height: 30px;
}

.subheading {
  @apply text-gray-1000 font-bold uppercase;
  font-size: 15px;
  line-spacing: 18px;
}

.par {
  @apply text-gray-1000 text-sm font-medium;
}

.bg-transition {
  animation: bg-opacity .3s ease-in-out;
}

@keyframes bg-opacity {
  0% {
    @apply bg-gray-400 bg-opacity-0;
    backdrop-filter: blur(0px);
  }

  50% {
    background-color: rgb(163, 171, 179, 0.5);
  }

  100% {
    @apply bg-gray-400 bg-opacity-25;
    backdrop-filter: blur(15px);
  }
}

@keyframes flyover {
  0% {
    transform: translateY(60%);
  }

  100% {
    transform: translateY(0%);
  }
}

@keyframes flyover-reverse {
  0% {
    transform: translateY(0%);
  }

  100% {
    transform: translateY(60%);
  }
}
</style>
<script>
export default {
  data () {
    return {
      show: false
    }
  },
  methods: {
    toggle : function() {
        this.show = !this.show;
      }
  }
}
</script>

1 Answers1

0

Generally speaking, adding transition to dynamically generated HTML5 elements can be a mess. Take a look at this great StackOverflow answer explaining why.

What you can do is using a v-show directive instead of a v-if. Vue will render your component and simply hide it with a display: none CSS property.

Gaetan C.
  • 1,742
  • 13
  • 21