Perché i componenti Tailwind ti salvano (e quando invece ti affogano)
Hai appena finito un sito con Tailwind. 700 righe di HTML. Ogni bottone è un clone di classi: px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700. Poi il cliente chiede: "cambiamo il colore primario da blu a verde". Ti tremano le mani. 47 file da modificare a mano. Questo è il problema che risolviamo oggi.
Noi, di Meteora Web, lavoriamo con Tailwind dal 2020. Abbiamo visto progetti diventare un inferno di manutenzione perché mancava una strategia di riutilizzo. E abbiamo visto team esplodere di produttività quando hanno capito la differenza tra @apply e componenti puri. Non è una guerra di religione: è una scelta tecnica che impatta i tuoi tempi di sviluppo e la sanità mentale del team.
Cosa fa @apply e perché non è sempre la risposta
@apply è una direttiva Tailwind che ti permette di raggruppare utility class in un unico selettore CSS. Invece di scrivere class="px-6 py-3 bg-blue-600 text-white rounded-lg" ogni volta, puoi fare:
/* styles.css */
.btn-primary {
@apply px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition;
}
E poi usare class="btn-primary" nel HTML. Sembra una manna. Funziona bene per classi di utilità atomiche che non variano.
Sponsored Protocol
Ma attenzione: @apply non è un sistema di componenti. È solo un modo per scrivere CSS più corto. Non gestisce stato, varianti (es. disabled, active), né composizione. Se devi avere un bottone primario, secondario, outline, con icona, senza icona, @apply ti costringe a creare 10 classi diverse. A quel punto ti ritrovi con un file CSS enorme e poca flessibilità.
Quando usare @apply? Per utility di basso livello che difficilmente cambiano: dimensioni fisse di padding, colori base, ombre. Mai per componenti interattivi o che devono variare in base al contesto.
Componenti puri: la scelta che paga nel lungo periodo
Con "componenti puri" intendiamo componenti JavaScript (React, Vue, Alpine.js) o anche semplicemente frammenti HTML con classi Tailwind inline gestiti attraverso un sistema di template (ad esempio in Laravel Blade o WordPress con parti riutilizzabili).
L'idea è semplice: ogni componente è un blocco autonomo che dichiara esplicitamente le sue classi Tailwind. Niente @apply, niente astrazioni extra. Ripeti le classi? Sì, ma il vantaggio è che ogni componente è leggibile al volo: guardi l'HTML e vedi esattamente cosa fa. Niente misteri di ereditarietà CSS.
Sponsored Protocol
Esempio con Alpine.js (ma funziona uguale con Vue o React):
Nota: non abbiamo usato @apply. Ogni variante è inline e condizionale. Il componente è autonomo, testabile, e si modifica senza toccare CSS globali.
Perché i componenti puri scalano meglio
- Nessun conflitto CSS: ogni componente gestisce il proprio stile. Niente war di specificità.
- Facile debugging: apri il componente, leggi le classi, capisci tutto.
- Gestione degli stati integrata: puoi usare props, variabili, condizionali direttamente nel markup.
- Riuso senza rigidità: lo stesso componente base può essere configurato con props diverse senza duplicare CSS.
@apply vs componenti puri: come scegliere nel tuo progetto
Non è bianco o nero. In molti progetti usiamo entrambi, ma con confini chiari.
Usa @apply per:
- Classi di layout base (es.
.container-max,.section-padding) - Utility atomiche come
.text-balanceo.scroll-smooth - Override di componenti di terze parti dove non puoi modificare il markup
Usa componenti puri per:
- Bottoni, card, form, navbar, footer — ogni elemento interattivo o ripetuto con varianti
- Ogni volta che hai più di 2 varianti dello stesso componente
- Componenti che gestiscono stato (loading, errore, vuoto)
La regola pratica: se il componente ha più di una variante, usa un componente puro. Se è una classe di utilità invariabile, @apply va bene.
Sponsored Protocol
Come implementare componenti Tailwind riutilizzabili in un progetto reale
Vediamo un workflow concreto, usando Laravel Blade (ma puoi adattarlo a qualsiasi template engine).
1. Crea una cartella components
In resources/views/components/ metti i tuoi file. Esempio: button.blade.php.
@props(['variant' => 'primary', 'disabled' => false])
Poi usalo nel tuo HTML:
Sponsored Protocol
Salva
Annulla
Niente @apply. Leggibile, estendibile con $attributes per aggiungere classi extra.
2. Usa Tailwind Merge per gestire le classi dinamicamente
Il pacchetto tailwind-merge (o clsx + tailwind-merge) risolve il conflitto tra classi. Esempio in React:
import { twMerge } from 'tailwind-merge'
function Button({ variant = 'primary', className, children }) {
const base = 'px-6 py-3 rounded-lg font-medium transition'
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300'
}
return (
)
}
Mai più conflitti tra classi passate dall'esterno e quelle interne.
Errori comuni (e come evitarli)
- @apply ovunque: finisci con un file CSS enorme e nessun vantaggio reale. Ogni modifica richiede di cercare la classe e aggiornarla, senza vedere il contesto HTML.
- Classi duplicate a manetta: se hai 50 bottoni con le stesse classi ma non li estrai in un componente, il refactoring è un incubo. Un componente puro risolve alla radice.
- Ignorare l'ereditarietà di Tailwind: @apply non risolve il problema delle varianti responsive o dark mode. Dovresti comunque usare classi condizionali, che rendono @apply meno utile.
- Non usare un sistema di design token: sia @apply che componenti puri beneficiano di variabili CSS per colori, spazi, font. Definisci i token nel tuo
tailwind.config.jse poi usali nelle classi.
Cosa fare adesso
- Analizza i tuoi attuali componenti: quanti bottoni, card, form hai? Se ripeti le stesse classi più di 3 volte, estrai un componente puro.
- Installa tailwind-merge (se usi React, Vue, o Alpine con JS) o usa la logica a mano nei template (Blade, Twig).
- Crea una libreria minima di componenti: inizia con Button, Card, Input. Testa con varianti. Poi espandi.
- Rimuovi gradualmente @apply da tutti i componenti interattivi. Lascia @apply solo per utility atomiche globali.
- Leggi la documentazione ufficiale di Reusing Styles per capire il punto di vista degli autori.
Approfondisci tutto il discorso su Tailwind CSS nella nostra guida principale.