Element clips contents while transitioning

Advertisements

I’m trying to build a generic Tabs component for my project with Svelte and TailwindCSS. When a tab is selected, I’d like the current contents to move as if they where being dragged by the new contents.

For whatever reason, when the transition starts, the current contents are clipped to an unknown height (it looks like it’s 50% of the height but can’t tell for sure and it always seems to be the same one) and I can’t figure it out what it is causing it. What’s weirder is that the new contents are not clipped despite having a similar animation.

The code for the tabs component:

<div class="grid grid-cols-1 grid-rows-[30px_auto] h-full overflow-x-clip">
    <ol class="flex flex-row">
        {#each tabs as tab, idx}
            <li class="mr-10">
              <button on:click|preventDefault={selectTab(idx)}>{tab.name}</button>
            </li>
        {/each}
    </ol>
    {#key selected}
        <div class="overflow-y-auto h-full min-h-full"
            out:fly={{
                x: Math.sign(selected - previous) * -100,
                y: 0,
                duration: duration / 2,
                easing: cubicIn
            }}
            in:fly={{
                x: Math.sign(selected - previous) * 100,
                y: 0,
                duration: duration / 2,
                delay: duration / 2,
                easing: cubicOut
            }}
        >
            <Products products={tabs[selected].products} />
        </div>
  {/key}
</div>

REPL

Here it is a GIF showing how it currently looks:

Please, notice how it always cuts the contents to the 6th element for unknown reasons.

How can I fix this clipping?

>Solution :

The container of the transitioning element has a grid layout.

During the transition the previous and next tab are both within said container, causing another grid row to be added, so the height of the tab content will be halved.

Wrap the transitioning element in a separate element, so you do not get multiple elements as grid children:

<div>
  {#key selected}
    <!-- Animated element here -->
  {/key}
</div>

REPL

There are also transition events that can be used to set some local state and apply additional classes during the transition to help with layout issues.

Leave a Reply Cancel reply