# Animazioni con Tailwind senza JavaScript

Tailwind anima con transizioni e keyframes CSS: transition-*, duration-* e animate-*, nessun runtime. Le uscite restano la parte difficile.

> Pagina: https://ui.eneawork.it/blog/tailwind-animazioni-css
> Markdown: https://ui.eneawork.it/blog/tailwind-animazioni-css.md

*2026-11-01*

Tailwind CSS anima con il solo CSS: le classi transition-*, duration-* e animate-* compilano in transizioni e keyframes, quindi il browser non esegue JavaScript per far muovere un elemento.

Nei 97 blocchi shadcn/ui salvati in data/cache/block-code (173 file, 496.045 caratteri) la classe animate-* compare 0 volte, transition-* 8 volte e duration-* 2 volte: misurate con node il 1 novembre 2026. Il catalogo EneUI conta 111.985 componenti, 1.556 blocchi e 12.808 icone da 1.472 librerie, letti da /api/stats lo stesso giorno. Tailwind CSS è distribuito con licenza MIT: repository tailwindlabs/tailwindcss, file LICENSE.

## Come si dichiara un'animazione

In Tailwind 4 il tema vive nel CSS: una variabile --animate-nome crea l'utility animate-nome, e i @keyframes stanno nello stesso blocco @theme. Non serve tailwind.config.js.

@import "tailwindcss"; @theme { --animate-slide-in: slide-in 240ms ease-out; @keyframes slide-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } }

Dopo la build l'elemento usa class="animate-slide-in" e il browser applica i keyframes senza ascoltare eventi. La documentazione tailwindcss.com, letta il 1 novembre 2026, descrive --animate-* come namespace del tema.

npx @tailwindcss/cli -i ./src/input.css -o ./dist/output.css --watch

Il comando richiede Node e riscrive dist/output.css a ogni salvataggio; il file src/input.css deve iniziare con @import "tailwindcss";.

## Transizioni di stato, non timeline

Per hover, focus e cambio di tema bastano transition-colors e duration-200: la proprietà cambia e il browser interpola. Per un ingresso legato a un attributo, come data-state="open", la variante data-[state=open]:animate-slide-in elimina il JavaScript di orchestrazione.

## Dove si rompe

L'uscita è la parte difficile: se il nodo esce dal DOM la transizione non parte. Servono transition-behavior: allow-discrete e @starting-style, oppure un listener transitionend che smonta il nodo dopo l'ultimo frame. Tailwind non orchestra sequenze e non ritarda lo smontaggio: quella decisione resta del componente.

## Dove continuare

Nel catalogo EneUI trovi typewriter, typing-animation e marquee along an SVG path, tutti costruiti con classi Tailwind. La definizione del framework è in che cos'è Tailwind CSS; il confronto tra librerie è in migliori librerie di animazione; il confronto tra approcci CSS è in Tailwind contro CSS modules. Gli altri due pezzi della serie sono focus-visible con Tailwind e stili di stampa con Tailwind.

## FAQ

### Serve JavaScript per animare con Tailwind?

No. Le classi compilano in transizioni e keyframes CSS, che il browser esegue da solo. Il JavaScript che scrivi resta quello del componente, non dell'animazione.

### Qual è la differenza tra transition-* e animate-*?

transition-* interpola un cambio di proprietà già avvenuto, per esempio su hover. animate-* esegue keyframes una volta o in loop, indipendentemente dal cambio di stato.

### Come si aggiunge un'animazione personalizzata?

Dichiari --animate-nome nel blocco @theme e scrivi i @keyframes nello stesso blocco. La build genera l'utility animate-nome, che usi come le altre classi.

### Tailwind rispetta prefers-reduced-motion?

Sì, con la variante motion-reduce, per esempio motion-reduce:animate-none. Il tema non la applica da solo: va scritta su ogni elemento animato.

### Perché la mia animazione non parte?

Di solito il nodo esce dal DOM prima della fine della transizione, oppure la classe viene costruita a runtime e non arriva al file CSS. Controlli la classe nel file generato e il momento in cui il nodo viene smontato.
