tailwindcss icon indicating copy to clipboard operation
tailwindcss copied to clipboard

Transitioning translateY on hover with tailwind results in weird text movement vs normal css transition

Open xjimdim opened this issue 5 months ago • 5 comments

What version of Tailwind CSS are you using? "@nuxtjs/tailwindcss": "6.10.1",

What build tool (or framework if it abstracts the build tool) are you using? Nuxt 3.8.2

What version of Node.js are you using? v20.10.0

What browser are you using? Chrome (latest)

What operating system are you using? Ubuntu 22.04.3 LTS

Reproduction URL https://play.tailwindcss.com/xUP0TJsg6r

Describe your issue For some reason when I use tailwind classes to transition an element's transform on hover to translateY(-2px); the text inside the element is moving while the transition is happening, resulting into a weird transition effect. In the reproduction url instead of the text moving around it seems like the height of the element is changing.

However if I use an oldschool css class with the same css properties the transition is smooth.

Any clues?

EDIT: Just realized that this visual bug is only happening when the chrome window is in my wide screen (2560x1080) and not in my main laptop screen (that has a normal 1080p resolution). Still this doesn't explain why the vanilla CSS solution works (even in my widescreen) and tailwind doesn't.

xjimdim avatar Dec 01 '23 08:12 xjimdim

Just a note for future me or anyone else looking at this — it appears to be resolved if we avoid applying any transform functions that aren't needed:

https://play.tailwindcss.com/JARCKkk47V

Normally translate-y-0 actually also applies rotate, scale, and skew but with "no-op" values because transform has historically been a single property that has to apply all of them together. If we switch to the modern dedicated translate property though it's fixed because we don't end up applying those other transforms. Still feels like a browser bug to me honestly.

Another potential change we could make in Tailwind is to store the entire function call in a variable (like --tw-rotate: rotate(4deg)) instead of just the 4deg part, and then the function would be not applied at all by default.

adamwathan avatar Dec 01 '23 17:12 adamwathan

As a workaround, adding the utility will-change-transform to the transitioning element stops this from happening in Chrome.

thecrypticace avatar Dec 01 '23 17:12 thecrypticace

I think this is a good solution to avoid unnecessary transform function invocations:

https://github.com/tailwindlabs/tailwindcss/compare/conditional-transforms?expand=1

Just need to update the test suite and think about any BC implications 👍

adamwathan avatar Dec 02 '23 02:12 adamwathan

This is interesting! I've noticed some "jank" sometimes with Tailwind translate-transitions, which go away if I switch to inset-transitions (or if I use will-change). Always found this odd, and it never occurred to me that it might have anything to do with Tailwind. (Also, I'd not heard of the translate/scale/rotate CSS properties before seeing this thread.)

MichaelAllenWarner avatar Dec 04 '23 14:12 MichaelAllenWarner

will-change can explicitly help with this issue: Josh W. Comeau's blog, MDN.

tommy-mitchell avatar Feb 01 '24 19:02 tommy-mitchell

We're avoiding this issue in v4 by using conditionally applied, individual transform properties (e.g. translate) for everything except skew-x and skew-y. In v3 and any other cases, will-change-transform should provide a workaround. Closing this based on those solutions. Let us know if we're still missing any cases!

KrisBraun avatar Mar 20 '24 19:03 KrisBraun