Search code examples
javascripthtmlcsssveltesvelte-transition

Svelte if-else connecting transitions


I have a page that has several stages, and I want to add transitions between them.

{#if state === 1}
 <div class="red" transition:fade/>
{:else if state === 2}
 <div class="blue" transition:fade/>
{:else if state === 3}
 <div class="green" transition:fade/>
{/if}

However, when switching from one state to the next, the next one appears at the same time as the previous one is still disappearing, so the two states would appear at the same time for the duration of the transition.

What is the best approach (the approach that requires adding the least amount of code) to make one state's fade in connect with another state's fade out?

Here is a code sandbox link: https://codesandbox.io/p/sandbox/priceless-pine-kgrh7w


Solution

  • One way would be to position the elements on top of each other with the help of a wrapper element

    REPL

    <script>
        import { fade } from 'svelte/transition';
        let state = 1;
    
        function handleClick() {
            state += 1;
            if (state == 4) state = 1;
        }
    </script>
    
    <main>
        <button on:click={handleClick}> Change </button>
        <div class="wrapper">
            {#if state === 1}
                <div class="red" transition:fade/>
            {:else if state === 2}
                <div class="blue" transition:fade/>
            {:else if state === 3}
                <div class="green" transition:fade/>
            {/if}
        </div>
    </main>
    
    <style>
        button {
            background: #ff3e00;
            color: white;
            border: none;
            padding: 8px 12px;
            border-radius: 2px;
        }
    
        .wrapper {
            display: grid;      
        }
    
        .wrapper > div {
            grid-column: 1;
            grid-row: 1;
            width: 100px;
            height: 100px;
        }
    
        .red {
            background: red;
        }
    
        .blue {
            background: blue;
        }
    
        .green {
            background: green;
        }
    </style>