'Tailwind CSS & Alpine JS opacity-slide-in transition

Hello dear amazing people, I am using Tailwind (CSS) and Alpine (JS) to create a multi-step form. And I want to create a transition for each step change.

I want the transition to be something simple yet nice, so I decided to do the following:

  • Have a container for all steps (individual screens/slides)
  • When moving from one step to the other, the transition should be:
    1. Step A fades out (opacity goes from 100 to 0)
    2. Step B slides in (margin left goes from -ml-5 to ml-0) while it fades in (opacity 0 --> 100)

According to the documentation for Alpine transition, it shall be done as follows:

<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet"/>

<div class="container" x-data="{ activeSlide: 1, slides: [1, 2, 3] }">
    <div class="relative" style="height:200px;">
        <!-- Slides -->
        <div class="absolute" style="height:200px;width:100%;background-color:blue;" x-show="activeSlide === 1" 
             x-transition:enter="transition ease-in-out duration-1000"
             x-transition:enter-start="-ml-5 opacity-0"
             x-transition:enter-end="ml-0 opacity-100"
             x-transition:leave="transition ease-in-out duration-1000"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0">
            Slide 1
        </div>
        <div class="absolute" style="height:200px;width:100%;background-color:orange;" x-show="activeSlide === 2"
             x-transition:enter="transition ease-in-out duration-1000"
             x-transition:enter-start="-ml-5 opacity-0"
             x-transition:enter-end="ml-0 opacity-100"
             x-transition:leave="transition ease-in-out duration-1000"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0">
            Slide 2
        </div>
        <div class="absolute" style="height:200px;width:100%;background-color:green;" x-show="activeSlide === 3"
             x-transition:enter="transition ease-in-out duration-1000"
             x-transition:enter-start="-ml-5 opacity-0"
             x-transition:enter-end="ml-0 opacity-100"
             x-transition:leave="transition ease-in-out duration-1000"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0">
            Slide 3
        </div>
    </div>
    <!-- Prev/Next arrow buttons -->
    <div class="box flex flex-space-between flex-middle">
        <button x-on:click="activeSlide = activeSlide === 1 ? slides.length : activeSlide - 1">←</button>
        <button x-on:click="activeSlide = activeSlide === slides.length ? 1 : activeSlide + 1">→</button>
    </div>
</div>

But I don't get the slide effect to happen. Any ideas? Thanks in advance.



Solution 1:[1]

In my experience, using margins for moving parts seem to never work as expected. Therefore I always utilize the translate classes provided by Tailwind:

<div class="container" x-data="{ activeSlide: 1, slides: [1, 2, 3] }">
    <div class="relative" style="height:200px;">
        <!-- Slides -->
        <div class="absolute" style="height:200px;width:100%;background-color:blue;" x-show="activeSlide === 1"
             x-transition:enter="transition ease-in-out duration-1000 transform"
             x-transition:enter-start="-translate-x-5 opacity-0"
             x-transition:enter-end="translate-x-0 opacity-100"
             x-transition:leave="transition ease-in-out duration-1000"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0">
            Slide 1
        </div>
        <div class="absolute" style="height:200px;width:100%;background-color:orange;" x-show="activeSlide === 2"
             x-transition:enter="transition ease-in-out duration-1000 transform"
             x-transition:enter-start="-translate-x-5 opacity-0"
             x-transition:enter-end="translate-x-0 opacity-100"
             x-transition:leave="transition ease-in-out duration-1000"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0">
            Slide 2
        </div>
        <div class="absolute" style="height:200px;width:100%;background-color:green;" x-show="activeSlide === 3"
             x-transition:enter="transition ease-in-out duration-1000 transform"
             x-transition:enter-start="-translate-x-5 opacity-0"
             x-transition:enter-end="translate-x-0 opacity-100"
             x-transition:leave="transition ease-in-out duration-1000"
             x-transition:leave-start="opacity-100"
             x-transition:leave-end="opacity-0">
            Slide 3
        </div>
    </div>
    <!-- Prev/Next arrow buttons -->
    <div class="box flex flex-space-between flex-middle">
        <button x-on:click="activeSlide = activeSlide === 1 ? slides.length : activeSlide - 1">?</button>
        <button x-on:click="activeSlide = activeSlide === slides.length ? 1 : activeSlide + 1">?</button>
    </div>
</div>    

Notice how I added a transform class to the x-transition:enter and a translate class to enter-start and enter-end.

You can read more about translate here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yinci