The symptom
I had a button with hover:scale-[1.02] and transition: transform 200ms ease-out. The scale wasn’t animating; it snapped straight to size. Changing the duration or the easing curve made no difference at all.
The cause
In Tailwind v3, scale-*, rotate-*, and translate-* composed into one transform value, so transition: transform covered all of them. Tailwind v4 doesn’t compose them anymore. It emits scale as its own CSS property, per CSS Transforms Level 2:
.hover\:scale-\[1\.02\]:hover {
scale: 1.02;
}
scale was never inside transform. My transition: transform rule was watching a property that never changed, and scale had no transition of its own, so it snapped instantly.
The fix
transition: filter 150ms, scale 150ms cubic-bezier(0.4, 0, 0.2, 1);
Adding scale to the transition list fixed it immediately. Tailwind’s own transition-transform utility already includes scale, rotate, and translate; the trap is only for hand-written transition: transform rules.
Takeaway
Utility classes are a convenient way to write CSS, but they’re not the CSS. When a change has no effect no matter how far you push it, check what’s actually being generated.