Sviluppo web
Animazioni con Tailwind senza JavaScript
Tailwind anima con transizioni e keyframes CSS: transition-*, duration-* e animate-*, nessun runtime. Le uscite restano la parte difficile.
In sintesi
- Le classi transition-*, duration-* e animate-* compilano in transizioni e keyframes CSS, senza runtime nel browser.
- In Tailwind 4 un'animazione nuova si dichiara nel tema con --animate-* e @keyframes nello stesso blocco.
- Nessuno dei 97 blocchi shadcn/ui in cache usa animate-*: l'animazione resta una scelta manuale.
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.
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.
- Una transizione CSS non blocca il thread principale e non aggiunge kilobyte di JavaScript.
- Con
motion-reduce:animate-nonerispettiprefers-reduced-motion, ma il test manuale resta obbligatorio. - I 97 blocchi in cache non animano nulla per default:
animate-*compare 0 volte. - Fonte: documentazione tailwindcss.com e licenza MIT del repository, lette il 1 novembre 2026.
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.
Domande frequenti
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.