Incorporating Tailwind CSS into Vue transitions reveals an issue where the fade out effect

I'm working with Tailwind CSS and Vue.js to create a modal component. Since Tailwind doesn't natively support Vue 2, I had to implement the transitions myself. You can check out the desired effect here.

Below is the code snippet:

<template>
  <div>
    <button @click="show = true">Click</button>

    <div v-show="show" class="fixed z-10 inset-0 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
      <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
        <transition name="ease-out-overlay">
          <div v-show="show" class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"></div>
        </transition>

        <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>

        <transition name="ease-out-modal">
          <div v-show="show" class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
            <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
              <div class="sm:flex sm:items-start">
                <div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
                  <svg class="h-6 w-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
                  </svg>
                </div>
                <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
                  <h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
                    Deactivate account
                  </h3>
                  <div class="mt-2">
                    <p class="text-sm text-gray-500">
                      Are you sure you want to deactivate your account? All of your data will be permanently removed. This action cannot be undone.
                    </p>
                  </div>
                </div>
              </div>
            </div>
            <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
              <button @click="show = false" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
                Deactivate
              </button>
              <button type="button" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
                Cancel
              </button>
            </div>
          </div>
        </transition>
      </div>
    </div>

  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop } from 'nuxt-property-decorator';

@Component
export default class TestModal extends Vue {
  @Prop({ type: Boolean, required: false })
  show: boolean = false;

  layout () {
    return 'none';
  }
}
</script>

<style scoped>

.ease-out-overlay-enter-active, .ease-out-overlay-leave-active {
  @apply opacity-100 duration-300;
}

.ease-out-overlay-enter, .ease-out-overlay-leave-to {
  @apply ease-in opacity-0 duration-200;
}

.ease-out-modal-enter-active, .ease-out-modal-leave-active {
  @apply opacity-100 translate-y-0 sm:scale-100 duration-300;
}

.ease-out-modal-enter, .ease-out-modal-leave-to {
  @apply ease-in opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95 duration-200;
}

</style>

The transition works well when the modal opens, but it doesn't animate when the modal closes. I'm unsure of the mistake I made in the implementation.

Do you have any suggestions on achieving a transition effect when closing the modal?

Answer №1

The issue arises from the lack of a transition around the tag that contains v-show="show" in line 6.

To resolve this, try enclosing that tag in another transition with the attribute

leave-active-class="duration-300"
. This will postpone its disappearance until the inner transitions are complete.

For reference, check out this example: https://codesandbox.io/s/nice-sky-o3be8?file=/pages/index.vue

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the reason for the difference in width between Bootstrap-5 row and regular div blocks?

My code may seem simple, but I have encountered an issue with it: <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="99fbf6f6edeaedebf8e9d9acb7abb7a9">[email protected]</a ...

How to send props from a Vue.js component tag in an HTML file

I'm facing an issue with passing props from the HTML to the JavaScript code and then down to a Vue component. Here's a snippet of my index.html file: <div id="js-group-discounts"> <div class="form-group required"> <datepick ...

Label positioning for checkboxes

Is there a way to display the checkbox label before the actual checkbox without using the "for" attribute in the label tag? I need to maintain the specific combination of the checkbox and label elements and cannot use nested labels or place other HTML elem ...

Words existing outside of an element

Currently, I am developing a slider using Bootstrap, and I have encountered an issue where the text displays on the left instead of aligning to the center in relation to the elements. To see this issue in action, you can check out the live demo here: In ...

Get the Zip file content using PushStreamContent JavaScript

I am looking for the correct method to download a PushStreamContent within a Post request. I have already set up the backend request like this: private static HttpClient Client { get; } = new HttpClient(); public HttpResponseMessage Get() { var filenames ...

"Is there a way to position a button at the bottom using HTML and

Is there a way to position my button after the reviews stars? The browser output screenshot shows the desired layout: https://i.sstatic.net/nh63E.png I want my post review button to be displayed after the reviews stars, not in a row. Here is the code s ...

Is there a reason why the slide up feature is not working when I include the ul tag?

I need help with a jQuery code that will pull up/slide up an Html "p" tag when my page finishes loading. This snippet of jQuery code seems to be working fine: $(function () { $('.graybgc').slideUp(0); }); This is the HTML structure: <p ...

The alignment of SVG is not in sync with the aspect ratio

I've been struggling with this issue for some time now, trying to align the SVGs correctly for different width and height values. My viewBox has an aspect ratio of 16:9, and I want to scale the SVG accordingly. It's working fine for certain combi ...

Can anyone explain why the animation doesn't work when deleting a div?

Using vue.js 2.9 in my current project, I have set up animations for transitions and translations: transform: translate3d(0, 0, 0) &.move-enter-active, &.move-leave-active transition: all 0.2s linear &.move-enter, &.move-leave transfor ...

Vue application experiencing an issue with data not being populated

I am having trouble retrieving data from my vuex store in a component using computed. Strangely, I am unable to access userInfo.uid in some of my components. Even though VueTools shows that it has been successfully imported, it keeps throwing an error stat ...

Divide text to reduce its width within the confines of a specific height on a div element

I've spent the past week scouring various forums, including stackoverflow, but I haven't been able to find a solution. In my responsive website, I'm using CSS flexbox to display dynamic menu items. Sometimes the text can be quite long, and ...

Vue2Editor not displaying updated content following data retrieval from axios call

I've encountered an issue with my Vue component that uses Vue2Editor. Everything was working great until I tried to update the content using data from an async function. To troubleshoot, I tested updating text in a simple div. Here's a snippet ...

Tips for asynchronously modifying data array elements by adding and slicing

I am facing an issue in my vuejs application where I need to modify an array of items after the app has finished loading. My current setup looks like this: var n = 100; var myData = []; function loadMovies(n){ // async ajax requests // add items to ...

Utilizing :checked selector and toggle() function in jQuery

I'm facing an issue with my jQuery code where the CSS changes are not working as expected. When I test the code, it doesn't apply the CSS changes. If I remove the :checked and just use $("input"), then the CSS works but only when clicking on an i ...

When hovering over nav bar links, shadows are not displayed

When hovering over the navbar links, I am able to change their color but a shadow at the bottom is missing. Is there a way to add a shadow at the bottom like it had before when not hovered? Visit this link for more information ...

Insert the URL into either a div or an iframe

It seems like a common issue. I've come across multiple solutions for this problem. using jquery load using iframe I attempted both methods but encountered difficulties in loading content. Specifically, I tried to load google.com and it didn't ...

React Images: Carousel display issue with images not centered

Is there a way to center the selected image instead of it appearing on the left-hand side? Here is the current behavior: https://i.stack.imgur.com/SUWOK.jpg I am using the following packages in a sandbox environment with Next.js 11 and TailwindCSS 2.2.4: ...

Experience the powerful combination of Nuxt 3 paired with TailwindCSS and heroicons. Elevate your

Looking for assistance in integrating Heroicons with Nuxt 3. I tried installing Heroicons using the command: yarn add @heroicons/vue In addition, I included @heroicons/vue in my nuxt.config.js: build: { transpile: ["@headlessui/vue", "@her ...

How can one effectively style text to appear italic using CSS and HTML?

What is the proper method to italicize text? I have come across these four different approaches: <i>Italic Text</i> <em>Italic Text</em> <span class="italic">Italic Text</span> <span class="footnote">Italic Tex ...

Find a solution for displaying custom product badges

Having some issues with a custom product badge on my website. I tried adding a new badge (besides "Sale"), but it seems to be displaying in the wrong position. The badge should display as "Choice" on the featured products, so I added this code to the chil ...