Motion and animation bring interfaces to life, providing feedback, drawing attention, and creating delightful user experiences. Tailwind provides comprehensive transform and transition utilities for scaling, rotating, translating elements, and animating changes smoothly. In this lesson, you'll master CSS transforms and transitions to create engaging, interactive interfaces.
Scale Transform
Scale transforms change the size of elements. Values represent percentages where 100 = 100% (original size):
Uniform Scaling
<!-- Scale down -->
<div class="scale-0">0% size (invisible)</div>
<div class="scale-50">50% size</div>
<div class="scale-75">75% size</div>
<div class="scale-90">90% size</div>
<div class="scale-95">95% size</div>
<!-- Normal size -->
<div class="scale-100">100% size (original)</div>
<!-- Scale up -->
<div class="scale-105">105% size</div>
<div class="scale-110">110% size</div>
<div class="scale-125">125% size</div>
<div class="scale-150">150% size</div>
<!-- Scale on hover -->
<button class="hover:scale-110 transition-transform">
Hover to grow
</button>
<!-- Scale on active/press -->
<button class="active:scale-95 transition-transform">
Click to shrink
</button>Directional Scaling
<!-- Scale X axis (horizontal) -->
<div class="scale-x-50">Narrow (50% width)</div>
<div class="scale-x-150">Wide (150% width)</div>
<!-- Scale Y axis (vertical) -->
<div class="scale-y-50">Short (50% height)</div>
<div class="scale-y-150">Tall (150% height)</div>
<!-- Combine X and Y scaling -->
<div class="scale-x-125 scale-y-75">
Wider and shorter
</div>
<!-- Stretch effect on hover -->
<div class="hover:scale-x-110 transition-transform">
Stretches horizontally
</div>Interactive Scale Examples
<!-- Card that grows on hover -->
<div class="bg-white rounded-lg shadow-lg p-6 hover:scale-105 transition-transform duration-300 cursor-pointer">
<h3 class="text-xl font-bold mb-2">Hover Card</h3>
<p>I grow when you hover over me!</p>
</div>
<!-- Button with press effect -->
<button class="bg-blue-500 text-white px-6 py-3 rounded-lg hover:scale-105 active:scale-95 transition-transform">
Press Me
</button>
<!-- Image zoom on hover -->
<div class="overflow-hidden rounded-lg">
<img
src="image.jpg"
alt="Zoom"
class="hover:scale-110 transition-transform duration-500"
>
</div>
<!-- Pulsing effect with group -->
<div class="group">
<div class="w-16 h-16 bg-blue-500 rounded-full group-hover:scale-110 transition-transform"></div>
</div>✨ Scale Best Practices
- Use
scale-105orscale-110for subtle hover effects - Pair with
transition-transformfor smooth animations - Use
active:scale-95for press/click feedback - Don't overdo it—large scales can be disorienting
Rotate Transform
Rotate transforms spin elements by specified degrees:
Basic Rotation
<!-- Clockwise rotation -->
<div class="rotate-0">No rotation (0°)</div>
<div class="rotate-1">1 degree</div>
<div class="rotate-3">3 degrees</div>
<div class="rotate-6">6 degrees</div>
<div class="rotate-12">12 degrees</div>
<div class="rotate-45">45 degrees</div>
<div class="rotate-90">90 degrees</div>
<div class="rotate-180">180 degrees (upside down)</div>
<!-- Counter-clockwise rotation -->
<div class="-rotate-45">-45 degrees</div>
<div class="-rotate-90">-90 degrees</div>
<div class="-rotate-180">-180 degrees</div>
<!-- Rotate on hover -->
<div class="hover:rotate-6 transition-transform">
Tilts on hover
</div>
<div class="hover:rotate-180 transition-transform duration-500">
Spins on hover
</div>Practical Rotation Examples
<!-- Chevron that rotates when expanded -->
<button class="flex items-center gap-2">
<span>Expand</span>
<svg class="w-5 h-5 rotate-0 group-[.expanded]:rotate-180 transition-transform" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
</svg>
</button>
<!-- Loading spinner -->
<svg class="animate-spin w-8 h-8 text-blue-500" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<!-- Plus icon that rotates to X -->
<button class="group">
<svg class="w-6 h-6 rotate-0 group-hover:rotate-45 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
</svg>
</button>
<!-- Card with tilted accent -->
<div class="relative bg-white rounded-lg p-6 overflow-hidden">
<div class="absolute top-0 right-0 w-32 h-32 bg-blue-500 rotate-12 transform translate-x-8 -translate-y-8"></div>
<div class="relative z-10">
<h3 class="text-xl font-bold">Content</h3>
</div>
</div>Translate Transform
Translate transforms move elements from their original position:
X-Axis Translation (Horizontal)
<!-- Move right (positive values) -->
<div class="translate-x-0">No movement</div>
<div class="translate-x-1">4px right</div>
<div class="translate-x-2">8px right</div>
<div class="translate-x-4">16px right</div>
<div class="translate-x-8">32px right</div>
<div class="translate-x-12">48px right</div>
<!-- Move left (negative values) -->
<div class="-translate-x-4">16px left</div>
<div class="-translate-x-8">32px left</div>
<!-- Percentage-based -->
<div class="translate-x-1/2">50% right (half width)</div>
<div class="translate-x-full">100% right (full width)</div>
<!-- Slide in from left on hover -->
<div class="-translate-x-full hover:translate-x-0 transition-transform">
Slides in from left
</div>Y-Axis Translation (Vertical)
<!-- Move down (positive values) -->
<div class="translate-y-0">No movement</div>
<div class="translate-y-4">16px down</div>
<div class="translate-y-8">32px down</div>
<!-- Move up (negative values) -->
<div class="-translate-y-4">16px up</div>
<div class="-translate-y-8">32px up</div>
<!-- Percentage-based -->
<div class="-translate-y-1/2">50% up (half height)</div>
<div class="-translate-y-full">100% up (full height)</div>
<!-- Float up on hover -->
<button class="hover:-translate-y-1 transition-transform">
Floats up on hover
</button>Centering with Translate
<!-- Perfect centering technique -->
<div class="relative h-64 bg-gray-100">
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
Perfectly centered
</div>
</div>
<!-- Center vertically only -->
<div class="relative h-64">
<div class="absolute top-1/2 -translate-y-1/2">
Vertically centered
</div>
</div>
<!-- Center horizontally only -->
<div class="relative">
<div class="absolute left-1/2 -translate-x-1/2">
Horizontally centered
</div>
</div>Practical Translation Examples
<!-- Floating action button -->
<button class="fixed bottom-8 right-8 w-14 h-14 bg-blue-500 text-white rounded-full shadow-lg hover:-translate-y-1 hover:shadow-xl transition-all">
+
</button>
<!-- Slide-in notification -->
<div class="fixed top-4 right-4 bg-green-500 text-white p-4 rounded-lg translate-x-full animate-slide-in">
Success! Saved.
</div>
<!-- Card that lifts on hover -->
<div class="bg-white rounded-lg shadow p-6 hover:-translate-y-2 hover:shadow-xl transition-all duration-300">
<h3 class="text-xl font-bold">Hover to lift</h3>
</div>
<!-- Dropdown menu -->
<div class="relative group">
<button>Menu</button>
<div class="absolute top-full mt-2 opacity-0 -translate-y-2 group-hover:opacity-100 group-hover:translate-y-0 transition-all">
<div class="bg-white shadow-lg rounded-lg p-4">
Menu items
</div>
</div>
</div>Skew Transform
Skew transforms slant elements along the X or Y axis:
<!-- Skew X axis -->
<div class="skew-x-0">No skew</div>
<div class="skew-x-3">3° skew</div>
<div class="skew-x-6">6° skew</div>
<div class="skew-x-12">12° skew</div>
<!-- Negative skew -->
<div class="-skew-x-6">-6° skew</div>
<div class="-skew-x-12">-12° skew</div>
<!-- Skew Y axis -->
<div class="skew-y-3">3° vertical skew</div>
<div class="skew-y-6">6° vertical skew</div>
<div class="-skew-y-6">-6° vertical skew</div>
<!-- Decorative skewed background -->
<div class="relative overflow-hidden">
<div class="absolute inset-0 bg-blue-500 skew-y-3 transform origin-top-left"></div>
<div class="relative z-10 p-8">
<h2 class="text-white text-2xl">Skewed Background</h2>
</div>
</div>
<!-- Skewed badge -->
<span class="inline-block bg-red-500 text-white px-4 py-1 skew-x-12">
SALE
</span>Transform Origin
Control the point around which transforms occur:
<!-- Default origin (center) -->
<div class="rotate-45 origin-center">
Rotates from center (default)
</div>
<!-- Corner origins -->
<div class="rotate-45 origin-top-left">
Rotates from top-left
</div>
<div class="rotate-45 origin-top">
Rotates from top-center
</div>
<div class="rotate-45 origin-top-right">
Rotates from top-right
</div>
<div class="rotate-45 origin-right">
Rotates from center-right
</div>
<div class="rotate-45 origin-bottom-right">
Rotates from bottom-right
</div>
<div class="rotate-45 origin-bottom">
Rotates from bottom-center
</div>
<div class="rotate-45 origin-bottom-left">
Rotates from bottom-left
</div>
<div class="rotate-45 origin-left">
Rotates from center-left
</div>
<!-- Card that flips from top -->
<div class="group perspective-1000">
<div class="relative transform-gpu transition-transform duration-500 group-hover:rotate-x-180 origin-top">
<div class="bg-white p-6 rounded-lg shadow-lg">
Hover to flip
</div>
</div>
</div>Transitions
Transitions make changes smooth and animated:
Basic Transitions
<!-- Transition all properties -->
<div class="transition-all hover:bg-blue-500">
Smooth transition on all properties
</div>
<!-- Transition specific properties -->
<div class="transition-colors hover:bg-blue-500">
Only colors transition smoothly
</div>
<div class="transition-transform hover:scale-110">
Only transform transitions smoothly
</div>
<div class="transition-opacity hover:opacity-50">
Only opacity transitions smoothly
</div>
<div class="transition-shadow hover:shadow-lg">
Only shadow transitions smoothly
</div>
<!-- No transition -->
<div class="transition-none hover:bg-blue-500">
Instant change (no transition)
</div>Transition Duration
<!-- Default duration (150ms) -->
<div class="transition hover:scale-110">
Default speed (150ms)
</div>
<!-- Custom durations -->
<div class="transition duration-75 hover:scale-110">
Very fast (75ms)
</div>
<div class="transition duration-100 hover:scale-110">
Fast (100ms)
</div>
<div class="transition duration-150 hover:scale-110">
Default (150ms)
</div>
<div class="transition duration-200 hover:scale-110">
Slow (200ms)
</div>
<div class="transition duration-300 hover:scale-110">
Slower (300ms)
</div>
<div class="transition duration-500 hover:scale-110">
Very slow (500ms)
</div>
<div class="transition duration-700 hover:scale-110">
Extra slow (700ms)
</div>
<div class="transition duration-1000 hover:scale-110">
1 second
</div>Transition Timing (Easing)
<!-- Linear (constant speed) -->
<div class="transition ease-linear hover:translate-x-4">
Linear timing
</div>
<!-- Ease in (slow start) -->
<div class="transition ease-in hover:translate-x-4">
Slow start, fast end
</div>
<!-- Ease out (slow end) -->
<div class="transition ease-out hover:translate-x-4">
Fast start, slow end
</div>
<!-- Ease in-out (slow start and end) -->
<div class="transition ease-in-out hover:translate-x-4">
Slow start and end (default)
</div>
<!-- Best for most animations -->
<div class="transition ease-out duration-300 hover:scale-110">
Recommended: ease-out
</div>Transition Delay
<!-- Delay before transition starts -->
<div class="transition delay-75 hover:scale-110">
75ms delay
</div>
<div class="transition delay-100 hover:scale-110">
100ms delay
</div>
<div class="transition delay-150 hover:scale-110">
150ms delay
</div>
<div class="transition delay-200 hover:scale-110">
200ms delay
</div>
<div class="transition delay-300 hover:scale-110">
300ms delay
</div>
<!-- Staggered animations -->
<div class="group">
<div class="transition delay-0 group-hover:translate-x-4">First</div>
<div class="transition delay-75 group-hover:translate-x-4">Second</div>
<div class="transition delay-150 group-hover:translate-x-4">Third</div>
</div>Combining Transforms
Multiple transforms can be combined on the same element:
<!-- Scale and rotate -->
<div class="hover:scale-110 hover:rotate-6 transition-transform">
Scales and rotates on hover
</div>
<!-- Translate and scale -->
<button class="hover:-translate-y-1 hover:scale-105 transition-all">
Lifts and grows
</button>
<!-- Multiple transforms with different timings -->
<div class="transition-all duration-300 hover:scale-110 hover:rotate-3 hover:-translate-y-2 hover:shadow-xl">
Complex hover effect
</div>
<!-- Card with 3D effect -->
<div class="group perspective-1000">
<div class="relative transition-transform duration-500 group-hover:scale-105 group-hover:-rotate-2 group-hover:-translate-y-2">
<div class="bg-white rounded-lg shadow-lg p-6">
<h3 class="text-xl font-bold">3D Card</h3>
<p>Hover for effect</p>
</div>
</div>
</div>Interactive Transform Explorer
Experiment with transforms and transitions:
Transform & Transition Explorer
Try different transforms with smooth transitions
Utilities
Current Classes:
bg-blue-500 text-white rounded-lg p-8 w-32 h-32 flex items-center justify-center font-boldPreview
Practical Transform Examples
Example 1: Interactive Button Collection
<!-- Lift effect -->
<button class="bg-blue-500 text-white px-6 py-3 rounded-lg hover:-translate-y-1 hover:shadow-lg transition-all">
Lift Button
</button>
<!-- Scale effect -->
<button class="bg-purple-500 text-white px-6 py-3 rounded-lg hover:scale-105 transition-transform">
Scale Button
</button>
<!-- Rotate effect -->
<button class="bg-green-500 text-white px-6 py-3 rounded-lg hover:rotate-2 transition-transform">
Rotate Button
</button>
<!-- Press effect -->
<button class="bg-red-500 text-white px-6 py-3 rounded-lg hover:scale-105 active:scale-95 transition-transform">
Press Button
</button>
<!-- Shimmer effect -->
<button class="relative bg-yellow-500 text-white px-6 py-3 rounded-lg overflow-hidden group">
<span class="relative z-10">Shimmer Button</span>
<div class="absolute inset-0 -translate-x-full group-hover:translate-x-full transition-transform duration-1000 bg-gradient-to-r from-transparent via-white/30 to-transparent"></div>
</button>Example 2: Animated Card Grid
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- Card 1: Lift and shadow -->
<div class="bg-white rounded-lg shadow hover:shadow-xl hover:-translate-y-2 transition-all duration-300 overflow-hidden">
<img src="image1.jpg" alt="Card" class="w-full h-48 object-cover">
<div class="p-6">
<h3 class="text-xl font-bold mb-2">Lift Card</h3>
<p class="text-gray-600">Lifts on hover with shadow</p>
</div>
</div>
<!-- Card 2: Scale and rotate -->
<div class="bg-white rounded-lg shadow overflow-hidden group">
<div class="overflow-hidden">
<img src="image2.jpg" alt="Card" class="w-full h-48 object-cover group-hover:scale-110 group-hover:rotate-2 transition-transform duration-300">
</div>
<div class="p-6">
<h3 class="text-xl font-bold mb-2">Image Zoom</h3>
<p class="text-gray-600">Image zooms on hover</p>
</div>
</div>
<!-- Card 3: Tilt effect -->
<div class="bg-white rounded-lg shadow hover:shadow-lg hover:rotate-1 hover:scale-105 transition-all duration-300 overflow-hidden">
<img src="image3.jpg" alt="Card" class="w-full h-48 object-cover">
<div class="p-6">
<h3 class="text-xl font-bold mb-2">Tilt Card</h3>
<p class="text-gray-600">Tilts and scales on hover</p>
</div>
</div>
</div>Example 3: Navigation with Transitions
<nav class="bg-white shadow">
<div class="max-w-7xl mx-auto px-4">
<div class="flex gap-1">
<!-- Active link -->
<a href="#" class="px-4 py-4 text-blue-600 border-b-2 border-blue-600 transition-colors">
Home
</a>
<!-- Hover links -->
<a href="#" class="px-4 py-4 text-gray-600 border-b-2 border-transparent hover:text-blue-600 hover:border-blue-600 transition-all">
About
</a>
<a href="#" class="px-4 py-4 text-gray-600 border-b-2 border-transparent hover:text-blue-600 hover:border-blue-600 transition-all">
Services
</a>
<a href="#" class="px-4 py-4 text-gray-600 border-b-2 border-transparent hover:text-blue-600 hover:border-blue-600 transition-all">
Contact
</a>
</div>
</div>
</nav>
<!-- Dropdown menu with transitions -->
<div class="relative group">
<button class="px-4 py-2 bg-blue-500 text-white rounded-lg">
Menu
<svg class="inline w-4 h-4 ml-1 transform group-hover:rotate-180 transition-transform" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
</svg>
</button>
<div class="absolute top-full mt-2 left-0 w-48 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200">
<div class="bg-white rounded-lg shadow-lg py-2 transform -translate-y-2 group-hover:translate-y-0 transition-transform">
<a href="#" class="block px-4 py-2 hover:bg-gray-100 transition-colors">Item 1</a>
<a href="#" class="block px-4 py-2 hover:bg-gray-100 transition-colors">Item 2</a>
<a href="#" class="block px-4 py-2 hover:bg-gray-100 transition-colors">Item 3</a>
</div>
</div>
</div>Example 4: Loading States
<!-- Spinning loader -->
<div class="w-12 h-12 border-4 border-gray-200 border-t-blue-500 rounded-full animate-spin"></div>
<!-- Pulsing dots -->
<div class="flex gap-2">
<div class="w-3 h-3 bg-blue-500 rounded-full animate-pulse"></div>
<div class="w-3 h-3 bg-blue-500 rounded-full animate-pulse delay-75"></div>
<div class="w-3 h-3 bg-blue-500 rounded-full animate-pulse delay-150"></div>
</div>
<!-- Bouncing loader -->
<div class="flex gap-2">
<div class="w-3 h-3 bg-blue-500 rounded-full animate-bounce"></div>
<div class="w-3 h-3 bg-blue-500 rounded-full animate-bounce delay-100"></div>
<div class="w-3 h-3 bg-blue-500 rounded-full animate-bounce delay-200"></div>
</div>
<!-- Progress bar -->
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
<div class="bg-blue-500 h-full transition-all duration-500" style="width: 60%"></div>
</div>
<!-- Skeleton loader -->
<div class="space-y-3">
<div class="h-4 bg-gray-200 rounded animate-pulse"></div>
<div class="h-4 bg-gray-200 rounded animate-pulse w-5/6"></div>
<div class="h-4 bg-gray-200 rounded animate-pulse w-4/6"></div>
</div>Example 5: Notification Toast
<!-- Slide in from right -->
<div class="fixed top-4 right-4 translate-x-full opacity-0 transition-all duration-300 data-[show=true]:translate-x-0 data-[show=true]:opacity-100">
<div class="bg-green-500 text-white p-4 rounded-lg shadow-lg flex items-center gap-3 min-w-[300px]">
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
</svg>
<div>
<p class="font-semibold">Success!</p>
<p class="text-sm">Your changes have been saved.</p>
</div>
</div>
</div>
<!-- Fade and scale in -->
<div class="fixed top-4 right-4 scale-95 opacity-0 transition-all duration-200 data-[show=true]:scale-100 data-[show=true]:opacity-100">
<div class="bg-blue-500 text-white p-4 rounded-lg shadow-lg">
<p class="font-semibold">New notification</p>
</div>
</div>Transforms & Transitions Playground
Practice creating animated interactions:
Create Animated Interactions
Experiment with transforms and transitions
Interactive Elements
Hover Card 1
Lifts with shadow on hover
Hover Card 2
Scales and tilts on hover
Transform & Transition Best Practices
Follow These Guidelines:
- Always add transitions: Use
transition-allor specific transition utilities - Keep it subtle: Small transforms (5-10%) usually work best
- Use ease-out: Most natural for interactions
- Duration matters: 200-300ms is usually ideal
- Combine transforms: Mix scale, translate, and rotate for rich effects
- Performance: Transform and opacity are GPU-accelerated
- Accessibility: Respect
prefers-reduced-motionfor users who need it - Test on devices: Animations perform differently on mobile
Key Takeaways
- Scale:
scale-*for sizing effects - Rotate:
rotate-*for rotation (0 to 180°) - Translate:
translate-x-*andtranslate-y-*for movement - Skew:
skew-x-*andskew-y-*for slanting - Transitions:
transition-*for smooth animations - Duration:
duration-*(75ms to 1000ms) - Timing:
ease-*for animation curves - Delay:
delay-*for staggered animations - Transforms can be combined for complex effects
- Always pair transforms with transitions for smooth animations
What's Next?
You've mastered transforms and transitions! You can now create engaging, interactive interfaces with smooth animations and delightful hover effects.
In the next lesson, we'll explore Filters & Visual Effects—learning to apply blur, brightness, contrast, grayscale, and backdrop filters to create stunning visual effects like frosted glass and image overlays.
🎯 Practice Challenge!
Create an interactive portfolio card that combines multiple effects: scale on hover, lift with shadow, rotate the image slightly, and add a smooth color transition to a button. Make the card fade in with a translate-y animation when it first appears. Ensure all animations are smooth with proper transitions!