Add life and interactivity to your UI with Tailwind's powerful animation utilities
Animations add life to your web applications, making interactions more engaging and intuitive. Tailwind CSS provides simple utilities to implement common animations and a framework for creating custom ones. Below are the key animation types and examples for each, with brief explanations.
Note: Animation utilities in Tailwind are enabled by default. Unlike transform and transition utilities which require the appropriate classes to enable them, animation utilities work right out of the box.
Tailwind comes with several pre-defined animations that you can use immediately in your projects. These animations are perfect for common UI patterns like loading indicators, notifications, and hover effects.
Perfect for loading indicators and spinners. Makes an element rotate continuously.
animate-spin
/* CSS Definition */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.animate-spin {
animation: spin 1s linear infinite;
}
Useful for notifications and attention-grabbers. Creates a quick scale and fade effect.
animate-ping
/* CSS Definition */
@keyframes ping {
75%, 100% {
transform: scale(2);
opacity: 0;
}
}
.animate-ping {
animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
}
Great for subtle loading states and drawing attention. Creates a gentle fading effect.
animate-pulse
/* CSS Definition */
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: .5;
}
}
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
Perfect for buttons and interactive elements. Creates a playful bouncing effect.
animate-bounce
/* CSS Definition */
@keyframes bounce {
0%, 100% {
transform: translateY(-25%);
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
}
50% {
transform: translateY(0);
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
}
.animate-bounce {
animation: bounce 1s infinite;
}
You can disable animations using the animate-none utility. This is useful for accessibility reasons or to stop animations conditionally.
animate-none
/* CSS Definition */
.animate-none {
animation: none;
}
You can define your own animations by extending the Tailwind configuration. This allows you to create animations specific to your project needs.
To add custom animations, you need to extend the animation and keyframes sections in your Tailwind config:
// tailwind.config.js
module.exports = {
theme: {
extend: {
animation: {
wiggle: 'wiggle 1s ease-in-out infinite',
float: 'float 3s ease-in-out infinite',
},
keyframes: {
wiggle: {
'0%, 100%': { transform: 'rotate(-12deg)' },
'50%': { transform: 'rotate(12deg)' },
},
float: {
'0%, 100%': { transform: 'translateY(0)' },
'50%': { transform: 'translateY(-20px)' },
}
}
}
}
}
A playful wiggle effect that rotates an element back and forth.
animate-wiggle
@keyframes wiggle {
0%, 100% { transform: rotate(-12deg); }
50% { transform: rotate(12deg); }
}
A gentle floating effect that moves an element up and down.
animate-float
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
When defining custom animations, you can specify several properties in addition to the keyframes:
Here are some real-world examples of how animations can be used to enhance the user experience.
animate-spin
A simple loading spinner using the spin animation on an SVG.
<!-- Loading Spinner with Tailwind CSS -->
<div class="flex items-center">
<svg class="animate-spin h-10 w-10 text-primary" xmlns="http://www.w3.org/2000/svg" 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>
<span class="ml-3 text-gray-700 text-lg">Loading...</span>
</div>
animate-ping
A notification bell with a ping animation to indicate new notifications.
<!-- Notification Bell with Ping Animation -->
<div class="relative">
<!-- Bell Icon -->
<svg class="h-12 w-12 text-gray-700" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
<!-- Animated Ping Notification Dot -->
<span class="absolute top-0 right-0 h-4 w-4 bg-red-500 rounded-full animate-ping"></span>
<!-- Static Dot (provides a solid background under the ping animation) -->
<span class="absolute top-0 right-0 h-4 w-4 bg-red-500 rounded-full"></span>
</div>
hover:animate-pulse
A button that pulses when hovered, combined with scale transform for a richer effect.
<!-- Interactive Button with Hover Animation -->
<button class="bg-primary hover:animate-pulse text-white font-bold py-3 px-6
rounded-lg text-lg transition-all duration-300 hover:shadow-lg
transform hover:scale-105">
Hover Me
</button>
<!--
This button combines multiple hover effects:
1. hover:animate-pulse - Adds the pulse animation when hovered
2. transition-all duration-300 - Makes all transitions smooth with 300ms duration
3. hover:shadow-lg - Increases the shadow when hovered
4. transform hover:scale-105 - Slightly scales up the button when hovered
-->
Your changes have been successfully saved!
animate-tadaa
A custom animation for success messages that scales in with a slight bounce.
<!-- Success Message with Custom Animation -->
<!-- First, define the custom animation in your Tailwind config -->
<script>
tailwind.config = {
theme: {
extend: {
animation: {
tadaa: 'tadaa 1s ease-in-out',
},
keyframes: {
tadaa: {
'0%': { transform: 'scale(0)', opacity: '0' },
'80%': { transform: 'scale(1.2)' },
'100%': { transform: 'scale(1)', opacity: '1' },
},
},
},
},
}
</script>
<!-- Then use the animation class -->
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 relative animate-tadaa">
<div class="flex">
<div class="flex-shrink-0">
<svg class="h-5 w-5 text-green-500" viewBox="0 0 20 20" fill="currentColor">
<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>
<div class="ml-3">
<p class="text-sm">Your changes have been successfully saved!</p>
</div>
</div>
</div>
Combining multiple animations and transitions can create rich interactive experiences.
Beautiful mountain scenery with amazing views.
Serene forest environment for the perfect getaway.
Crystal clear waters and golden sands await.
This example combines several animation techniques:
<!-- Interactive Card with Multiple Hover Animations -->
<div class="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-xl
transition-shadow duration-300 group">
<!-- Image container with overflow hidden to contain the scaling image -->
<div class="h-48 flex items-center justify-center overflow-hidden">
<!-- Image with scale effect on group hover -->
<img src="image.jpg" alt="Mountain"
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500">
</div>
<div class="p-6">
<!-- Heading with color transition on group hover -->
<h4 class="font-bold text-gray-800 mb-2 group-hover:text-primary transition-colors">
Mountain View
</h4>
<p class="text-gray-600 text-sm">Beautiful mountain scenery with amazing views.</p>
<!-- Button with pulse animation on group hover -->
<button class="mt-4 px-4 py-2 bg-primary text-white rounded group-hover:animate-pulse">
Explore
</button>
</div>
</div>
<!--
Key Techniques Used:
1. Group hover - Using the 'group' class on the parent and 'group-hover:' prefix on children
2. Transitions - Adding transition-* classes for smooth effects
3. Transform - Using scale for image zoom effect
4. Animation - Adding animate-pulse to the button only when the card is hovered
5. Shadow - Enhancing the shadow on hover for a "lifting" effect
-->
While animations can enhance the user experience, they can also cause problems for some users. Here are some important considerations:
Some users experience discomfort, dizziness, or nausea from animated content, especially those with vestibular disorders.
Users can specify that they prefer reduced motion through their operating system settings. Tailwind provides a way to respect this preference:
/* Only animate when the user hasn't specified a preference */
@media (prefers-reduced-motion: no-preference) {
.animate-safe-spin {
animation: spin 1s linear infinite;
}
}
You can create variants in your Tailwind config to make this easier:
// tailwind.config.js
module.exports = {
theme: {
/* ... */
},
variants: {
animation: ['responsive', 'motion-safe', 'motion-reduce']
}
}