iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Animations

Tailwind ships a small built-in animation set (spin, ping, pulse, bounce) plus the building blocks (transition, duration, ease) for state-driven animation. For complex sequences, drop into a CSS keyframe defined in tailwind.config.js or reach for Framer Motion. The built-ins cover most loading states, button feedback, and toast entrances.

Built-ins, transitions, custom keyframes, motion-safe

EXAMPLE
<!-- 1) Built-in spinners and pulses -->
<svg class='animate-spin h-5 w-5 text-white' viewBox='0 0 24 24'>
  <circle cx='12' cy='12' r='10' stroke='currentColor' stroke-width='4' fill='none' opacity='.3' />
  <path fill='currentColor' d='M4 12a8 8 0 0 1 8-8v2a6 6 0 0 0-6 6H4z' />
</svg>
<span class='animate-ping inline-flex h-3 w-3 rounded-full bg-emerald-400 opacity-75'></span>
<div class='animate-pulse bg-slate-200 h-4 w-32 rounded'></div>
<div class='animate-bounce text-blue-500'>v</div>

<!-- 2) Hover and focus transitions — state-driven, not keyframed -->
<button class='px-3 py-1.5 rounded bg-blue-600 text-white
                transition-transform duration-150 ease-out
                hover:scale-105 active:scale-95
                focus-visible:ring-2 focus-visible:ring-blue-400'>
  Save
</button>

<!-- 3) Group hover — child animates on parent hover -->
<a href='#' class='group inline-flex items-center gap-1'>
  Continue
  <span class='transition-transform duration-200 group-hover:translate-x-1'>→</span>
</a>

<!-- 4) Stagger via delay utilities -->
<div class='space-y-1'>
  <p class='opacity-0 animate-fadeUp [animation-delay:0ms]'>One</p>
  <p class='opacity-0 animate-fadeUp [animation-delay:80ms]'>Two</p>
  <p class='opacity-0 animate-fadeUp [animation-delay:160ms]'>Three</p>
</div>

<!-- 5) Respect 'prefers-reduced-motion' — use motion-safe / motion-reduce variants -->
<div class='motion-safe:animate-bounce motion-reduce:animate-none'>Bouncing only when allowed</div>

<!-- 6) Custom keyframes in tailwind.config.js -->
<!-- tailwind.config.js
module.exports = {
  theme: {
    extend: {
      keyframes: {
        fadeUp:  { '0%': { opacity: 0, transform: 'translateY(8px)' },
                   '100%': { opacity: 1, transform: 'translateY(0)' } },
        shimmer: { '100%': { transform: 'translateX(100%)' } },
      },
      animation: {
        fadeUp:  'fadeUp .35s ease-out forwards',
        shimmer: 'shimmer 1.4s linear infinite',
      },
    },
  },
};
-->

<!-- 7) Skeleton loader with shimmer -->
<div class='relative overflow-hidden bg-slate-200 rounded h-4 w-40'>
  <div class='absolute inset-0 -translate-x-full
              bg-gradient-to-r from-transparent via-white/50 to-transparent
              animate-shimmer'></div>
</div>

<!-- 8) Enter / leave transitions (Headless UI, Vue, Alpine all use Tailwind utilities) -->
<div class='transition duration-200 ease-out
            data-[state=open]:opacity-100 data-[state=open]:translate-y-0
            data-[state=closed]:opacity-0 data-[state=closed]:translate-y-2
            data-[state=closed]:pointer-events-none'>
  Toast
</div>

<!-- 9) Performance — animate transform and opacity (GPU-composited).
     Avoid animating width / height / margin in hot paths; they trigger layout. -->

Why it matters

Always pair motion with `motion-safe:` (or check `prefers-reduced-motion` in custom CSS). Users who opt out of motion include people with vestibular disorders, and the OS-level setting is the universal contract — respecting it is a 5-character class name and the right thing to do.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
<div class="animate-spin">⏳</div>
Try it Yourself »

Discussion

Loading…