Menu

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.

ClassPropertiesExample
duration-0transition-duration: 0s;<div className="duration-0"></div>
duration-75transition-duration: 75ms;<div className="duration-75"></div>
duration-100transition-duration: 100ms;<div className="duration-100"></div>
duration-150transition-duration: 150ms;<div className="duration-150"></div>
duration-200transition-duration: 200ms;<div className="duration-200"></div>
duration-300transition-duration: 300ms;<div className="duration-300"></div>
duration-500transition-duration: 500ms;<div className="duration-500"></div>
duration-700transition-duration: 700ms;<div className="duration-700"></div>
duration-1000transition-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:

This is a live editor. Play around with it!
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.

This is a live editor. Play around with it!
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.

This is a live editor. Play around with it!
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:

This is a live editor. Play around with it!
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.

This is a live editor. Play around with it!
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.

This is a live editor. Play around with it!
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.

This is a live editor. Play around with it!
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.

This is a live editor. Play around with it!
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.

This is a live editor. Play around with it!
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.

This is a live editor. Play around with it!
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.

This is a live editor. Play around with it!
// 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.

This is a live editor. Play around with it!
// 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.

This is a live editor. Play around with it!
// 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.