Tailwind Transition Duration Not Working?
Quick guide to repairing Tailwind duration issues
Ever hit Run and watched your beautifully-animated button just snap open at light-speed? You’re not alone. The fix is nearly always a missing utility, a wrong-way config, or another library secretly stomping on your CSS. Below you’ll find the common traps, quick checklists, framework-specific tips, and four bite-size FAQs so you can get smooth again in minutes.
How Tailwind Really Applies Duration
Tailwind only respects a duration-*
class after you’ve told the browser what should transition with transition
or transition-all
utilities. The docs show the pattern clearly:
<button class="transition duration-300 ease-in-out">...</button>
If the transition
utility is missing, the duration-300
is dead weight.
Out of the box, Tailwind provides eight duration values (75 ms → 1 s) and picks 150 ms as the default when you use transition
alone.
Why Your Duration Gets Ignored
1. The transition class is added conditionally
Frameworks that toggle classes in the same render tick (React/Vue/Alpine) can skip the animation frame the browser needs, so the element appears instantly.
Fix: add the transition
+ duration-*
classes permanently and toggle only the stateful classes (e.g., opacity-0
↔ opacity-100
).
2. Another library overwrites the default
NextUI and some component kits inject their own transitionDuration
in a compiled CSS layer, overriding Tailwind’s.
Fix: explicitly extend all the duration values in tailwind.config.js
—don’t just replace DEFAULT
, or you’ll lose the rest.
3. You accidentally set duration to 0 ms
Developers sometimes add '0': '0ms'
thinking it helps with toggles; but if that class sneaks in, every animation becomes instant.
4. Framework quirks
React: rapid re-renders or misuse of
key
props can destroy the animation state.Vue: wrapping the element in
<transition>
orv-show
without matching CSS can override Tailwind utilities.Next.js: dynamic class strings built from data need all possible classes present at build time, or PurgeCSS wipes them.
Quick-Fix Checklist
Pair utilities:
transition
(ortransition-all
) +duration-XYZ
+ easing (ease-in-out
)—every time.Don’t replace defaults blindly: extend
transitionDuration
instead of overwriting.Purge-safe class names: list full class strings in your code or safelist them.
Inspect generated CSS: DevTools > Computed > transition-duration shows who wins.
Restart dev server: Tailwind only recompiles when it sees config changes.
Check plugin order: PostCSS plugin stacking can put third-party CSS after Tailwind, overriding it.
Framework-Specific Tips
React / Next.js
Wrap state changes in requestAnimationFrame
or setTimeout(0)
if a component mounts and animates in the same tick. Keep all transition
utilities static in the JSX string.
Vue (3 & Nuxt)
Prefer @vueuse/motion
or Tailwind utilities directly instead of <transition>
unless you also write matching CSS classes. Remove v-show
for opacity fades; it sets display:none
and kills transitions.
General Plugin Ecosystem
When you add a UI kit, scan its compiled CSS for .transition
rules. If you spot transition-duration: 250ms
, either reorder your CSS or create a higher-specificity utility (e.g., !.duration-300
).
Wrap-Up
Nine times out of ten, a missing transition
utility or a rogue config entry is the culprit. Confirm the classes, scan your compiled CSS, and you’ll restore buttery animations in minutes.
FAQ
Why does duration-300 work on hover but not when I toggle a class in JavaScript?
Because the hover state gives the browser a full paint cycle, while instant JS toggles need a tiny delay to let the style settle first.
Does adding !important to my duration class help?
Rarely; it only helps when another stylesheet overrides Tailwind. Fix the selector order instead of sprinkling !important.
My modal fades out fine, but fades in instantly—what gives?
You probably removed the transition class when the modal is hidden; keep transition + duration-* on the element at all times.
Can I safely set a new default duration in tailwind.config.js?
Yes—extend the transitionDuration object instead of replacing it, or you’ll erase the built-in values.

Yucel is a digital product creator and content writer with a knack for full-stack development. He loves blending technical know-how with engaging storytelling to build practical, user-friendly solutions. When he's not coding or writing, you'll likely find him exploring new tech trends or getting inspired by nature.