Tailwind CSS Transition Duration
Transition duration is a critical CSS property used to define the length of time a visual transition takes to complete. It controls the pacing of transitions applied to properties such as colors, borders, or positioning. Tailwind CSS comes with pre-defined utilities to handle transition durations, offering a quick and scalable way to implement rich, interactive designs.
In this guide, we’ll explore the transition duration utilities in Tailwind CSS, covering fundamental usage, conditionally applying states, customizing durations, and much more.
Class | Properties | Example |
---|---|---|
duration-0 | transition-duration: 0s; | <div className="duration-0"></div> |
duration-75 | transition-duration: 75ms; | <div className="duration-75"></div> |
duration-100 | transition-duration: 100ms; | <div className="duration-100"></div> |
duration-150 | transition-duration: 150ms; | <div className="duration-150"></div> |
duration-200 | transition-duration: 200ms; | <div className="duration-200"></div> |
duration-300 | transition-duration: 300ms; | <div className="duration-300"></div> |
duration-500 | transition-duration: 500ms; | <div className="duration-500"></div> |
duration-700 | transition-duration: 700ms; | <div className="duration-700"></div> |
duration-1000 | transition-duration: 1000ms; | <div className="duration-1000"></div> |
Overview of Transition Duration
Adding the Transition Duration
Transition durations control the time span for transitions applied to styles. Apply duration-*
utilities to set the duration of a transition:
export default function TransitionDurationDemo() { return ( <div className="flex items-center justify-center w-screen h-screen bg-gray-100"> <button className="px-6 py-3 bg-blue-500 text-white rounded-lg duration-1000 hover:bg-blue-700"> Hover Me </button> </div> ); }
States and Responsiveness
Hover and Focus States
Transitions often need to be conditional, responding to user interactions like hover or focus. Tailwind facilitates this by combining transition classes with state variants.
export default function HoverFocusDemo() { return ( <div className="flex items-center justify-center w-screen h-screen bg-gray-100"> <button className="px-6 py-3 bg-green-500 text-white rounded-lg duration-1000 hover:duration-200 hover:bg-green-700"> Click Me </button> </div> ); }
Breakpoint Modifiers
Different screen sizes often require unique transition durations. Tailwind’s breakpoint modifiers enable developers to define responsive transition durations.
export default function ResponsiveDurationDemo() { return ( <div className="flex items-center justify-center w-screen h-screen bg-gray-100"> <button className="px-6 py-3 bg-purple-500 text-white rounded-lg sm:duration-200 md:duration-500 lg:duration-700 hover:bg-purple-700"> Click Me </button> </div> ); }
Custom Transition Duration
Extending the Theme
Tailwind allows you to customize themes if the default duration utilities don’t meet your requirements. For instance, you may want durations not included by default, like 750ms
. To add such custom values, extend your Tailwind configuration file:
import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function CustomTransitionDemo() { return ( <div className="flex items-center justify-center w-screen h-screen bg-gray-100"> <button className="px-6 py-3 bg-red-500 text-white rounded-lg duration-750 hover:bg-red-700"> Custom Duration </button> </div> ); }
Using Arbitrary Values
For ultimate flexibility, arbitrary values are a powerful feature in Tailwind CSS. You can specify exact durations outside the pre-defined or theme-extended values.
export default function ArbitraryValuesDemo() { return ( <div className="flex items-center justify-center w-screen h-screen bg-gray-100"> <button className="px-6 py-3 bg-yellow-500 text-white rounded-lg duration-[850ms] hover:bg-yellow-700"> Arbitrary Duration </button> </div> ); }
Real World Examples
Animated Product Cards Showcase
A product grid that reveals additional information with smooth transitions when hovering over each card.
export default function ProductShowcase() { const products = [ { id: 1, name: "Premium Leather Backpack", price: "$129.99", image: "https://images.unsplash.com/photo-1622560480605-d83c853bc5c3", alt: "Brown leather backpack" }, { id: 2, name: "Wireless Headphones", price: "$199.99", image: "https://images.unsplash.com/photo-1505740420928-5e560c06d30e", alt: "Black wireless headphones" }, { id: 3, name: "Smart Watch Pro", price: "$299.99", image: "https://images.unsplash.com/photo-1546868871-7041f2a55e12", alt: "Modern smartwatch" }, { id: 4, name: "Digital Camera", price: "$799.99", image: "https://images.unsplash.com/photo-1516035069371-29a1b244cc32", alt: "Professional camera" }, { id: 5, name: "Gaming Console", price: "$499.99", image: "https://images.unsplash.com/photo-1486401899868-0e435ed85128", alt: "Gaming console" }, { id: 6, name: "Tablet Pro", price: "$649.99", image: "https://images.unsplash.com/photo-1544244015-0df4b3ffc6b0", alt: "Modern tablet" } ]; return ( <div className="grid gap-6 p-8"> {products.map((product) => ( <div key={product.id} className="group relative overflow-hidden rounded-lg shadow-lg" > <img src={product.image} alt={product.alt} className="w-full h-64 object-cover transition-transform duration-500 group-hover:scale-110" /> <div className="absolute bottom-0 left-0 right-0 bg-black bg-opacity-70 text-white p-4 transform translate-y-full transition-transform duration-1000 group-hover:translate-y-0"> <h3 className="text-xl font-bold">{product.name}</h3> <p className="text-lg">{product.price}</p> </div> </div> ))} </div> ); }
Staggered Menu Animation
A navigation menu with staggered item animations on hover.
const StaggeredMenu = () => { const menuItems = [ { title: "Dashboard", icon: "https://images.unsplash.com/photo-1461773518188-b3e86f98242f", description: "View your analytics and reports" }, { title: "Projects", icon: "https://images.unsplash.com/photo-1507925921958-8a62f3d1a50d", description: "Manage your ongoing projects" }, { title: "Messages", icon: "https://images.unsplash.com/photo-1526554850534-7c78330d5f90", description: "Check your inbox and communications" }, { title: "Calendar", icon: "https://images.unsplash.com/photo-1506784693919-ef06d93c28d2", description: "Schedule and manage appointments" }, { title: "Settings", icon: "https://images.unsplash.com/photo-1507457379470-08b800bebc67", description: "Configure your account preferences" }, { title: "Support", icon: "https://images.unsplash.com/photo-1488426862026-3ee34a7d66df", description: "Get help and contact support" } ]; return ( <nav className="w-64 bg-gray-800 h-screen p-4"> <div className="space-y-2"> {menuItems.map((item, index) => ( <div key={index} className="group relative transition-all duration-300 hover:bg-gray-700 rounded-lg cursor-pointer" style={{ transitionDelay: `${index * 50}ms` }} > <div className="p-3 flex items-center space-x-3"> <img src={item.icon} alt={`${item.title} icon`} className="w-6 h-6 rounded transition-transform duration-300 group-hover:scale-110" /> <div> <h3 className="text-white font-medium">{item.title}</h3> <p className="text-gray-400 text-sm opacity-0 max-h-0 transition-all duration-300 group-hover:opacity-100 group-hover:max-h-12"> {item.description} </p> </div> </div> </div> ))} </div> </nav> ); }; export default StaggeredMenu;
Animated Feature Cards
Interactive feature cards with smooth transition effects for icons and content.
export default function FeatureCards() { const features = [ { id: 1, icon: "https://images.unsplash.com/photo-1460925895917-afdab827c52f", title: "Cloud Storage", description: "Secure and scalable cloud storage solutions" }, { id: 2, icon: "https://images.unsplash.com/photo-1526374965328-7f61d4dc18c5", title: "Data Analytics", description: "Advanced analytics and reporting tools" }, { id: 3, icon: "https://images.unsplash.com/photo-1550751827-4bd374c3f58b", title: "Cybersecurity", description: "Enterprise-grade security measures" }, { id: 4, icon: "https://images.unsplash.com/photo-1451187580459-43490279c0fa", title: "API Integration", description: "Seamless third-party integrations" }, { id: 5, icon: "https://images.unsplash.com/photo-1551288049-bebda4e38f71", title: "Machine Learning", description: "AI-powered business solutions" }, { id: 6, icon: "https://images.unsplash.com/photo-1518770660439-4636190af475", title: "24/7 Support", description: "Round-the-clock technical assistance" } ]; return ( <div className="grid gap-8 p-8"> {features.map((feature) => ( <div key={feature.id} className="group p-6 bg-white rounded-xl shadow-lg hover:shadow-xl transition-all duration-500" > <div className="h-16 w-16 rounded-full overflow-hidden mb-4 transform transition-transform duration-500 group-hover:scale-110"> <img src={feature.icon} alt={feature.title} className="w-full h-full object-cover" /> </div> <h3 className="text-xl font-bold mb-2 transition-colors duration-300 group-hover:text-blue-600"> {feature.title} </h3> <p className="text-gray-600 transition-colors duration-300 group-hover:text-gray-800"> {feature.description} </p> </div> ))} </div> ); }
Animated Team Members Grid
A responsive team members grid with smooth hover transitions and social media links.
export default function TeamGrid() { const team = [ { id: 1, name: "John Smith", role: "CEO", image: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e", alt: "John Smith profile picture", social: { twitter: "#", linkedin: "#", github: "#" } }, // Add 5 more team members similarly ]; return ( <div className="grid gap-8 p-8"> {team.map((member) => ( <div key={member.id} className="relative group overflow-hidden rounded-lg" > <img src={member.image} alt={member.alt} className="w-full h-80 object-cover transition-transform duration-500 group-hover:scale-110" /> <div className="absolute inset-0 bg-gradient-to-t from-black to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"> <div className="absolute bottom-0 left-0 right-0 p-6"> <h3 className="text-white text-xl font-bold transform translate-y-4 transition-transform duration-300 group-hover:translate-y-0"> {member.name} </h3> <p className="text-gray-300 transform translate-y-4 transition-transform duration-500 group-hover:translate-y-0"> {member.role} </p> </div> </div> </div> ))} </div> ); }
Accordion FAQ
An FAQ section with smooth expanding and collapsing animations.
import {useState} from "react" const FAQAccordion = () => { const faqs = [ { question: "What payment methods do you accept?", answer: "We accept all major credit cards, PayPal, and bank transfers. For business accounts, we also offer invoice payment options." }, { question: "How long does shipping take?", answer: "Domestic shipping typically takes 2-4 business days. International shipping can take 7-14 business days depending on the destination." }, { question: "What is your return policy?", answer: "We offer a 30-day return policy for unused items in their original packaging. Refunds are processed within 5-7 business days." }, { question: "Do you offer bulk discounts?", answer: "Yes, we offer tiered discounts for bulk orders. Contact our sales team for a custom quote based on your quantity requirements." }, { question: "How do I track my order?", answer: "Once your order ships, you'll receive a tracking number via email. You can use this to track your package on our website." }, { question: "What warranty do you provide?", answer: "All products come with a standard 1-year manufacturer warranty. Extended warranty options are available for purchase." } ]; const [activeIndex, setActiveIndex] = useState(null); return ( <div className="max-w-2xl mx-auto p-6 space-y-4"> {faqs.map((faq, index) => ( <div key={index} className="border rounded-lg overflow-hidden" > <button onClick={() => setActiveIndex(activeIndex === index ? null : index)} className="w-full p-4 text-left bg-white hover:bg-gray-50 transition-colors duration-300 flex justify-between items-center" > <span className="font-medium">{faq.question}</span> <span className={`transform transition-transform duration-300 ${activeIndex === index ? 'rotate-180' : ''}`} > ↓ </span> </button> <div className={`overflow-hidden transition-all duration-500 ease-in-out ${activeIndex === index ? 'max-h-48' : 'max-h-0'}`} > <p className="p-4 bg-gray-50 text-gray-700"> {faq.answer} </p> </div> </div> ))} </div> ); }; export default FAQAccordion;
Customization Examples
Animated Product Card Hover Effect
Configure custom transition durations for a smooth product card animation that reveals additional details on hover.
// App.js import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function ProductCard() { return ( <div className="max-w-sm mx-auto"> <div className="relative overflow-hidden rounded-lg shadow-lg group"> <img src="https://images.unsplash.com/photo-1542291026-7eec264c27ff" alt="Product" className="w-full duration-2000 transform group-hover:scale-110" /> <div className="absolute inset-0 bg-black bg-opacity-50 duration-3000 transform translate-y-full group-hover:translate-y-0"> <div className="p-6 text-white"> <h3 className="text-2xl font-bold">Limited Edition Sneakers</h3> <p className="mt-2">Premium comfort, distinctive style</p> <button className="mt-4 px-6 py-2 bg-white text-black rounded-full"> View Details </button> </div> </div> </div> </div> ); }
Elegant Menu Transition
Create a sophisticated menu transition with custom durations for different elements.
// App.js import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function NavigationMenu() { return ( <nav className="bg-gray-900 p-6"> <div className="max-w-4xl mx-auto"> <div className="flex items-center justify-between"> <img src="https://images.unsplash.com/photo-1599305445671-ac291c95aaa9" alt="Logo" className="w-12 h-12 rounded-full duration-1500 hover:rotate-180" /> <div className="space-x-8"> {['Products', 'About', 'Contact'].map((item) => ( <button key={item} className="text-white relative group" > {item} <span className="absolute bottom-0 left-0 w-0 h-0.5 bg-white duration-2500 group-hover:w-full" /> </button> ))} </div> </div> </div> </nav> ); }
Feature Section Reveal
Implement a staggered reveal effect for feature sections with custom transition timings.
// App.js import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function FeatureSection() { return ( <div className="max-w-6xl mx-auto p-8 bg-gradient-to-r from-purple-500 to-pink-500"> <div className="grid gap-8"> {[ { icon: "https://images.unsplash.com/photo-1611162617474-5b21e879e113", title: "Cloud Storage", description: "Secure and scalable storage solutions" }, { icon: "https://images.unsplash.com/photo-1551288049-bebda4e38f71", title: "Analytics", description: "Advanced data insights" }, { icon: "https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d", title: "Security", description: "Enterprise-grade protection" } ].map((feature, index) => ( <div key={feature.title} className="group p-6 bg-white rounded-xl shadow-xl hover:scale-105 duration-800" > <img src={feature.icon} alt={feature.title} className="w-16 h-16 rounded-lg mb-4 duration-4000 group-hover:rotate-12" /> <h3 className="text-xl font-bold mb-2">{feature.title}</h3> <p className="text-gray-600">{feature.description}</p> </div> ))} </div> </div> ); }
Best Practices
Maintain Design Consistency
Achieving a consistent design language is crucial when working with transition duration in Tailwind CSS. By defining and adhering to a standardized set of transition duration values, you can create a unified user experience across your project.
For instance, setting uniform durations for similar interactions, such as button hover effects or modal animations, ensures users perceive the interface as cohesive. Tailwind provides pre-defined duration utilities like duration-150
and duration-300
, which can be consistently applied across components for this purpose.
Leverage Utility Combinations
Combining multiple Tailwind CSS utilities with transition duration can help create sophisticated and dynamic interfaces while maintaining clarity in your code. For instance, pairing duration-200
with ease-in-out
and transform can make animations feel smooth and natural. These utilities are most effective when used together to enhance user interaction, such as scaling a card on hover or fading in a tooltip.
You can also combine transition duration with delay-*
utilities to create staggered animations or delay the start of certain effects. For example, pairing delay-100
with duration-300
allows you to control the timing and order of animations, creating visually appealing interactions like staggered list animations. These combinations are especially useful in storytelling interfaces, where dynamic content needs to draw attention progressively.
Accessibility Considerations
Enhance Readability and Navigability
Transition duration impacts how users perceive and interact with content. By setting appropriate durations, you can improve readability and navigability for all users. For instance, using duration-200
for hover states on buttons ensures that users can clearly identify active elements without unnecessary delays.
Ensuring consistent durations for navigational elements, such as menus or tabs, enhances usability. When transitions are predictable and uniform, users can easily identify patterns, making navigation more intuitive. Avoid overly long durations that may confuse or frustrate users, particularly in interactive elements.
Focus on High Contrast
High contrast is a fundamental aspect of accessibility, and transition duration can help reinforce this principle. For example, pairing duration-150
with transition-colors
ensures that color changes in interactive elements, such as buttons or links, are immediate and noticeable. This is particularly important for users with low vision, who rely on clear visual cues to navigate interfaces.
Additionally, use transition-transform
and duration-300
to emphasize changes in scale or position, drawing attention to critical elements. For instance, scaling up a button on hover provides a clear visual cue, improving accessibility for users who may struggle with fine motor control.