Tailwind CSS

Transitions & Animations

20 min Lesson 15 of 35

Transitions & Animations in Tailwind CSS

Transitions and animations bring your interface to life by adding smooth, polished motion effects. Tailwind CSS provides powerful utilities for controlling CSS transitions and includes pre-built animations that you can apply instantly. Understanding these tools is essential for creating modern, engaging user experiences.

Transition Property

The transition utilities specify which CSS properties should animate when they change:

Transition Property Examples

<!-- Transition all properties -->
<button class="transition-all bg-blue-500 hover:bg-blue-600 hover:scale-110 text-white px-4 py-2 rounded">
    Hover Me
</button>

<!-- Transition specific properties -->
<button class="transition-colors bg-blue-500 hover:bg-blue-700 text-white px-4 py-2 rounded">
    Colors Only
</button>

<button class="transition-transform hover:scale-110 bg-green-500 text-white px-4 py-2 rounded">
    Transform Only
</button>

<button class="transition-opacity hover:opacity-50 bg-purple-500 text-white px-4 py-2 rounded">
    Opacity Only
</button>

<button class="transition-shadow hover:shadow-lg bg-red-500 text-white px-4 py-2 rounded">
    Shadow Only
</button>

<!-- No transition -->
<button class="transition-none bg-gray-500 hover:bg-gray-700 text-white px-4 py-2 rounded">
    No Transition
</button>
Performance Tip: transition-all is convenient but can affect performance. For best results, specify only the properties you need to animate: transition-colors, transition-transform, transition-opacity, or transition-shadow.

Transition Duration

Duration utilities control how long a transition takes to complete:

Duration Examples

<!-- Different durations -->
<button class="transition-all duration-75 hover:scale-110 bg-blue-500 text-white px-4 py-2 rounded mr-2">
    75ms (very fast)
</button>

<button class="transition-all duration-150 hover:scale-110 bg-blue-500 text-white px-4 py-2 rounded mr-2">
    150ms (default)
</button>

<button class="transition-all duration-300 hover:scale-110 bg-blue-500 text-white px-4 py-2 rounded mr-2">
    300ms (medium)
</button>

<button class="transition-all duration-500 hover:scale-110 bg-blue-500 text-white px-4 py-2 rounded mr-2">
    500ms (slow)
</button>

<button class="transition-all duration-700 hover:scale-110 bg-blue-500 text-white px-4 py-2 rounded mr-2">
    700ms (slower)
</button>

<button class="transition-all duration-1000 hover:scale-110 bg-blue-500 text-white px-4 py-2 rounded">
    1000ms (slowest)
</button>
Best Practice: Use 150-300ms for most UI interactions. Shorter durations (75-150ms) for immediate feedback, longer durations (500-1000ms) for dramatic effects or complex animations.

Timing Functions (Easing)

Timing functions control the acceleration curve of transitions, making animations feel more natural:

Timing Function Examples

<!-- Linear (constant speed) -->
<div class="transition-all duration-500 ease-linear hover:translate-x-64 bg-blue-500 text-white p-4 rounded mb-4">
    Linear
</div>

<!-- Ease-in (slow start) -->
<div class="transition-all duration-500 ease-in hover:translate-x-64 bg-green-500 text-white p-4 rounded mb-4">
    Ease In
</div>

<!-- Ease-out (slow end) -->
<div class="transition-all duration-500 ease-out hover:translate-x-64 bg-yellow-500 text-white p-4 rounded mb-4">
    Ease Out
</div>

<!-- Ease-in-out (slow start and end) -->
<div class="transition-all duration-500 ease-in-out hover:translate-x-64 bg-red-500 text-white p-4 rounded mb-4">
    Ease In-Out
</div>
When to Use:
  • ease-in - Elements entering the screen
  • ease-out - Elements exiting the screen (most common)
  • ease-in-out - Elements that need smooth start and end
  • ease-linear - Loading spinners and continuous animations

Transition Delay

Delay utilities postpone the start of a transition:

Delay Examples

<!-- Staggered animations -->
<div class="space-y-4">
    <div class="transition-all duration-300 delay-0 hover:translate-x-8 bg-blue-500 text-white p-4 rounded">
        No delay
    </div>
    <div class="transition-all duration-300 delay-75 hover:translate-x-8 bg-blue-500 text-white p-4 rounded">
        75ms delay
    </div>
    <div class="transition-all duration-300 delay-150 hover:translate-x-8 bg-blue-500 text-white p-4 rounded">
        150ms delay
    </div>
    <div class="transition-all duration-300 delay-300 hover:translate-x-8 bg-blue-500 text-white p-4 rounded">
        300ms delay
    </div>
    <div class="transition-all duration-300 delay-500 hover:translate-x-8 bg-blue-500 text-white p-4 rounded">
        500ms delay
    </div>
    <div class="transition-all duration-300 delay-700 hover:translate-x-8 bg-blue-500 text-white p-4 rounded">
        700ms delay
    </div>
    <div class="transition-all duration-300 delay-1000 hover:translate-x-8 bg-blue-500 text-white p-4 rounded">
        1000ms delay
    </div>
</div>

<!-- Hover parent to see staggered effect -->
<div class="group bg-gray-100 p-8 rounded-lg">
    <h3 class="text-xl font-bold mb-4">Hover this container</h3>
    <div class="opacity-0 group-hover:opacity-100 transition-opacity duration-300 delay-0 bg-blue-500 text-white p-3 rounded mb-2">
        Appears first
    </div>
    <div class="opacity-0 group-hover:opacity-100 transition-opacity duration-300 delay-150 bg-blue-500 text-white p-3 rounded mb-2">
        Appears second
    </div>
    <div class="opacity-0 group-hover:opacity-100 transition-opacity duration-300 delay-300 bg-blue-500 text-white p-3 rounded">
        Appears third
    </div>
</div>
Use Case: Delays are perfect for creating staggered animations where elements appear one after another, giving a polished, professional feel to your interface.

Built-in Animations

Tailwind includes several pre-built animations that you can use instantly:

Animation Examples

<!-- Spin animation (loading spinner) -->
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500"></div>

<!-- Ping animation (notification dot) -->
<div class="relative inline-flex">
    <span class="absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75 animate-ping"></span>
    <span class="relative inline-flex rounded-full h-3 w-3 bg-blue-500"></span>
</div>

<!-- Pulse animation (loading state) -->
<div class="animate-pulse bg-gray-300 h-4 rounded w-full"></div>

<!-- Bounce animation (attention grabber) -->
<svg class="animate-bounce w-6 h-6 text-blue-500">
    <!-- Down arrow icon -->
</svg>

<!-- None (disable animation) -->
<div class="animate-none">No animation</div>

Spin Animation

Loading Spinner Examples

<!-- Basic spinner -->
<div class="flex items-center justify-center">
    <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500"></div>
</div>

<!-- Spinner with thickness -->
<div class="animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-500"></div>

<!-- Spinner button -->
<button class="bg-blue-500 text-white px-6 py-3 rounded-lg flex items-center gap-2" disabled>
    <div class="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div>
    Loading...
</button>

<!-- Full page loading -->
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
    <div class="bg-white rounded-lg p-8">
        <div class="animate-spin rounded-full h-16 w-16 border-t-4 border-b-4 border-blue-500 mx-auto"></div>
        <p class="mt-4 text-gray-600">Loading...</p>
    </div>
</div>

Ping Animation

Notification Examples

<!-- Notification badge -->
<button class="relative">
    <svg class="w-6 h-6"><!-- Bell icon --></svg>
    <span class="absolute top-0 right-0 inline-flex">
        <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
        <span class="relative inline-flex rounded-full h-3 w-3 bg-red-500"></span>
    </span>
</button>

<!-- Live indicator -->
<div class="flex items-center gap-2">
    <div class="relative">
        <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
        <span class="relative inline-flex rounded-full h-3 w-3 bg-green-500"></span>
    </div>
    <span class="text-sm font-medium text-gray-700">Live</span>
</div>

<!-- Status card -->
<div class="border border-gray-200 rounded-lg p-4 flex items-center gap-4">
    <div class="relative flex-shrink-0">
        <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-blue-400 opacity-75"></span>
        <span class="relative inline-flex rounded-full h-4 w-4 bg-blue-500"></span>
    </div>
    <div>
        <p class="font-semibold">System Active</p>
        <p class="text-sm text-gray-600">All systems operational</p>
    </div>
</div>

Pulse Animation

Skeleton Loading Examples

<!-- Card skeleton -->
<div class="border border-gray-200 rounded-lg p-6 space-y-4">
    <div class="animate-pulse flex space-x-4">
        <div class="rounded-full bg-gray-300 h-12 w-12"></div>
        <div class="flex-1 space-y-3 py-1">
            <div class="h-4 bg-gray-300 rounded w-3/4"></div>
            <div class="h-4 bg-gray-300 rounded w-1/2"></div>
        </div>
    </div>
</div>

<!-- List skeleton -->
<div class="space-y-4">
    <div class="animate-pulse">
        <div class="h-4 bg-gray-300 rounded w-full"></div>
    </div>
    <div class="animate-pulse">
        <div class="h-4 bg-gray-300 rounded w-5/6"></div>
    </div>
    <div class="animate-pulse">
        <div class="h-4 bg-gray-300 rounded w-4/6"></div>
    </div>
</div>

<!-- Image skeleton -->
<div class="animate-pulse bg-gray-300 rounded-lg w-full h-64"></div>

Bounce Animation

Bounce Examples

<!-- Scroll indicator -->
<div class="flex flex-col items-center">
    <p class="text-gray-600 mb-2">Scroll down</p>
    <svg class="animate-bounce w-6 h-6 text-blue-500">
        <!-- Down arrow -->
    </svg>
</div>

<!-- Call to action -->
<button class="relative bg-blue-500 text-white px-8 py-4 rounded-lg font-semibold">
    Get Started
    <span class="absolute -top-1 -right-1 animate-bounce">
        <span class="flex h-3 w-3">
            <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-400 opacity-75"></span>
            <span class="relative inline-flex rounded-full h-3 w-3 bg-red-500"></span>
        </span>
    </span>
</button>

<!-- Error icon -->
<div class="flex items-center gap-2 text-red-600">
    <svg class="animate-bounce w-5 h-5">!</svg>
    <span>Error occurred</span>
</div>

Combining Transitions with Hover States

Create smooth, interactive components by combining transitions with hover and focus states:

Interactive Component Examples

<!-- Card with multiple transition effects -->
<div class="group bg-white border border-gray-200 rounded-xl overflow-hidden transition-all duration-300 hover:shadow-2xl hover:-translate-y-2">
    <img src="image.jpg" class="w-full h-48 object-cover transition-transform duration-500 group-hover:scale-110" alt="Card">
    <div class="p-6">
        <h3 class="text-xl font-bold transition-colors duration-300 group-hover:text-blue-600">
            Card Title
        </h3>
        <p class="text-gray-600 mt-2 transition-colors duration-300 group-hover:text-gray-900">
            Card description text
        </p>
        <button class="mt-4 bg-blue-500 text-white px-6 py-2 rounded-lg transition-all duration-300 hover:bg-blue-600 hover:shadow-lg hover:scale-105">
            Learn More
        </button>
    </div>
</div>

<!-- Button with icon slide -->
<button class="group relative bg-green-500 hover:bg-green-600 text-white px-8 py-3 rounded-lg overflow-hidden transition-colors duration-300">
    <span class="relative z-10 flex items-center gap-2">
        Continue
        <svg class="w-5 h-5 transition-transform duration-300 group-hover:translate-x-1">→</svg>
    </span>
    <span class="absolute inset-0 bg-gradient-to-r from-green-600 to-green-700 transform -translate-x-full group-hover:translate-x-0 transition-transform duration-300"></span>
</button>

<!-- Nav link with underline animation -->
<a href="#" class="relative text-gray-700 hover:text-blue-600 transition-colors duration-300">
    About Us
    <span class="absolute left-0 bottom-0 w-0 h-0.5 bg-blue-600 transition-all duration-300 group-hover:w-full"></span>
</a>

<!-- Input with focus effects -->
<input
    type="text"
    placeholder="Search..."
    class="w-full border-2 border-gray-300 rounded-lg px-4 py-3 transition-all duration-300 focus:border-blue-500 focus:ring-4 focus:ring-blue-200 focus:outline-none"
>

<!-- Toggle switch -->
<button class="relative inline-flex h-8 w-14 items-center rounded-full bg-gray-300 transition-colors duration-300 focus:outline-none focus:ring-4 focus:ring-blue-300">
    <span class="inline-block h-6 w-6 transform rounded-full bg-white transition-transform duration-300 translate-x-1"></span>
</button>

<!-- Toggle switch (active state) -->
<button class="relative inline-flex h-8 w-14 items-center rounded-full bg-blue-500 transition-colors duration-300 focus:outline-none focus:ring-4 focus:ring-blue-300">
    <span class="inline-block h-6 w-6 transform rounded-full bg-white transition-transform duration-300 translate-x-7"></span>
</button>
Performance Warning: Avoid animating properties like width, height, top, left, margin, or padding as they trigger layout recalculation. Prefer transform and opacity for best performance.

Practical Animation Patterns

Modal Fade-In

Modal with Transitions

<!-- Modal container (add/remove with JavaScript) -->
<div class="fixed inset-0 z-50 overflow-y-auto transition-opacity duration-300 opacity-0 hidden" id="modal">
    <!-- Background overlay -->
    <div class="fixed inset-0 bg-black bg-opacity-50 transition-opacity duration-300"></div>

    <!-- Modal content -->
    <div class="flex min-h-full items-center justify-center p-4">
        <div class="relative bg-white rounded-lg shadow-xl max-w-md w-full transform transition-all duration-300 scale-95">
            <div class="p-6">
                <h2 class="text-2xl font-bold">Modal Title</h2>
                <p class="mt-4">Modal content</p>
            </div>
        </div>
    </div>
</div>

<!-- JavaScript to show modal:
Remove 'hidden' class
After a short delay, add 'opacity-100' and 'scale-100'
-->

Accordion Slide

Animated Accordion

<div class="space-y-2">
    <div class="border border-gray-200 rounded-lg overflow-hidden">
        <button class="w-full flex items-center justify-between p-4 text-left hover:bg-gray-50 transition-colors duration-200">
            <span class="font-semibold">Section 1</span>
            <svg class="w-5 h-5 transition-transform duration-300 rotate-0">↓</svg>
        </button>
        <div class="max-h-0 overflow-hidden transition-all duration-300 ease-in-out">
            <div class="p-4 border-t border-gray-200">
                <p>Section 1 content</p>
            </div>
        </div>
    </div>

    <!-- Expanded state: rotate-180 on icon, max-h-96 on content -->
    <div class="border border-gray-200 rounded-lg overflow-hidden">
        <button class="w-full flex items-center justify-between p-4 text-left hover:bg-gray-50 transition-colors duration-200">
            <span class="font-semibold">Section 2</span>
            <svg class="w-5 h-5 transition-transform duration-300 rotate-180">↓</svg>
        </button>
        <div class="max-h-96 overflow-hidden transition-all duration-300 ease-in-out">
            <div class="p-4 border-t border-gray-200">
                <p>Section 2 content (expanded)</p>
            </div>
        </div>
    </div>
</div>

Exercise 1: Create an Animated Product Card

Build a product card that features:

  • Image that scales up on card hover (transform + duration-500)
  • Card that lifts with shadow increase (translate-y + shadow-2xl)
  • Price badge that slides in from the side
  • "Add to Cart" button that appears with fade and slide up
  • All animations use appropriate easing and durations
  • Stagger delays for a polished effect

Exercise 2: Build a Loading State System

Create a comprehensive loading system with:

  • Button with inline spinner (animate-spin)
  • Skeleton loaders for card content (animate-pulse)
  • Progress indicator with animated bar
  • Notification badge with ping effect
  • Full-page loading overlay with spinner
  • Smooth transitions between loading and loaded states

Exercise 3: Design an Interactive Navigation

Create a navigation bar where:

  • Nav links have animated underline on hover (width transition)
  • Dropdown menu slides down with fade (opacity + translate-y)
  • Mobile menu slides in from the side (transform)
  • Active link has a smooth background color transition
  • Logo pulses subtly on page load
  • All interactions feel smooth with proper timing functions

Summary

In this lesson, you've mastered transitions and animations in Tailwind CSS:

  • Transition property: Control which properties animate (all, colors, transform, opacity, shadow)
  • Duration: Set animation speed from 75ms to 1000ms
  • Timing functions: Create natural motion with ease-in, ease-out, ease-in-out, and linear
  • Delay: Create staggered animations with delayed starts
  • Built-in animations: spin, ping, pulse, and bounce for common patterns
  • Combining with states: Create interactive components with hover, focus, and group modifiers
  • Performance: Use transform and opacity for smooth, performant animations

Transitions and animations are essential for creating modern, engaging user interfaces. They provide visual feedback, guide user attention, and make your application feel polished and professional. Remember to use them thoughtfully—too much animation can be distracting, while well-placed transitions enhance the user experience.