# Motion Library + Tailwind Conflicts

**SHOULD** · **ID:** `animations-motion-tailwind-conflict` · **Category:** animations
**Source:** Custom
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/animations-motion-tailwind-conflict

> SHOULD: When using Framer Motion/Motion with Tailwind, remove conflicting `transition-*` classes from animated elements. Let Motion handle transitions to prevent stuttery/weird motion.

Remove Tailwind transition classes from elements animated by Framer Motion

Tailwind's transition-* classes apply CSS transitions. When combined with Framer Motion's JS-based animations, they conflict and cause stuttering. Use Motion's transition prop instead.

## Bad — do not do this

`animations-motion-tailwind-conflict-bad`

```tsx
import { useState } from 'react';
import { motion } from 'motion/react';

export function MotionTailwindConflictBad() {
  const [on, setOn] = useState(false);

  return (
    <div className="space-y-4">
      <button
        onClick={() => setOn((v) => !v)}
        className="px-4 py-2 rounded-lg bg-primary text-primary-foreground transition-colors duration-150 ease-out hover:bg-primary/90"
      >
        Toggle (spam me)
      </button>
      <div className="h-20 flex items-center">
        <motion.div
          animate={{ x: on ? 160 : 0 }}
          transition={{ type: 'spring', stiffness: 300, damping: 20 }}
          // BAD: a Tailwind transition on the very transform Motion is animating
          className="size-14 rounded-xl bg-primary transition-transform duration-300"
        />
      </div>
      <p className="text-xs text-destructive">
        A Tailwind <code>transition-transform</code> on a Motion element — CSS and Motion both write <code>transform</code>, so rapid toggles stutter and fight
      </p>
    </div>
  );
}
```

## Good — do this

`animations-motion-tailwind-conflict-good`

```tsx
import { useState } from 'react';
import { motion } from 'motion/react';

export function MotionTailwindConflictGood() {
  const [on, setOn] = useState(false);

  return (
    <div className="space-y-4">
      <button
        onClick={() => setOn((v) => !v)}
        className="px-4 py-2 rounded-lg bg-primary text-primary-foreground transition-colors duration-150 ease-out hover:bg-primary/90"
      >
        Toggle (spam me)
      </button>
      <div className="h-20 flex items-center">
        <motion.div
          animate={{ x: on ? 160 : 0 }}
          transition={{ type: 'spring', stiffness: 300, damping: 20 }}
          className="size-14 rounded-xl bg-primary"
        />
      </div>
      <p className="text-xs text-success">
        Motion owns the <code>transform</code> — no Tailwind transition class fighting it, so the spring stays smooth even when spammed
      </p>
    </div>
  );
}
```

## References

- [Motion + Tailwind Guide](https://motion.dev/docs/react-tailwind)
- [Framer Motion + Tailwind 2025](https://dev.to/manukumar07/framer-motion-tailwind-the-2025-animation-stack-1801)
