Skip to content
Advertisement

Tailwind animation plays twice when changing pages in Next.js?

I’m using react-hot-toast to show alerts & animate it while changing pages.

The animation plays fades in twice when page changes.

I’m using tailwindcss-animate in my tailwind.config.js to add animation classes.

I’m only using 4 animation classes: animate-in, animate-out, fade-in, & fade-out

I am animating a custom Success alert box.

Success.tsx

import toast, { ToastOptions } from 'react-hot-toast';
import { CheckCircleIcon } from '@heroicons/react/outline';
import clsx from 'clsx';

interface ISuccess {
  message: string;
  options?: ToastOptions;
}

export const Success = ({ message, options }: ISuccess) => {
  toast.custom(
    (t) => (
      <div
        className={clsx(
          'flex rounded-lg bg-gray-900 py-2.5 px-3 shadow-lg ring-1 ring-black ring-opacity-5',
          {
            'animate-in fade-in': t.visible,
            'fade-out animate-out': !t.visible,
          }
        )}
      >
        <CheckCircleIcon className="h-6 w-6 text-gray-700" />
        <div className="ml-2 text-gray-300">{message}</div>
      </div>
    ),
    {
      duration: 250,
      ...options,
    }
  );
};

If you click the link in the demo below, then you should see the animation play twice like the gif below:

gif demo

How do I fix it so it only plays once?

Stackblitz Demo → https://stackblitz.com/edit/animate-in-tailwind

Github Repo → https://github.com/deadcoder0904/animate-in-tailwind/

Advertisement

Answer

When you switch the animation using t.visible, the fadeIn and fadeOut css properties of the finishing keyframe will not preserve. In other words, the Opacity: 0 will be removed, causing the node appear again. You can try to add style={{ animationFillMode: 'forwards' }} to retain the computed values set by the last keyframe.

Example:

<div
    style={{ animationFillMode: 'forwards' }}
    className={clsx(
      'flex rounded-lg bg-gray-900 py-2.5 px-3 shadow-lg ring-1 ring-black ring-opacity-5',
      {
        'animate-in fade-in': t.visible,
        'fade-out animate-out': !t.visible,
      }
    )}
  >

You can also change the animation fill mode by adding class name fill-mode-forwards if you are using tailwind-animation.

Example:

<div
    className={clsx(
      'flex rounded-lg bg-gray-900 py-2.5 px-3 shadow-lg ring-1 ring-black ring-opacity-5',
      {
        'animate-in fade-in fill-mode-forwards': t.visible,
        'fade-out animate-out fill-mode-forwards': !t.visible,
      }
    )}
  >
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement