5 agosto 2026
Props (for that): la libreria che fa parlare JavaScript e CSS senza incollare tutto a mano
Passa a CSS valori “vivi” come pointer, visibilità, viewport e velocità di scroll con una configurazione minimale e un occhio alla performance.
Coordinare JS e CSS di solito significa: listener, state, custom properties aggiornate a mano e (spesso) qualche compromesso di performance. Props (for that) cambia l’approccio: dichiari cosa ti serve su un elemento e ottieni variabili CSS già pronte, aggiornate in modo efficiente e solo quando l’elemento è realmente in gioco. Risultato: interazioni, glow, tilt e reveal su scroll con pochissimo codice e logica molto più pulita.
Quando costruiamo micro-interazioni “ricche” (tilt al passaggio del mouse, gradienti che inseguono il cursore, elementi che entrano in viewport con un twist), il pattern classico è sempre lo stesso:
- JavaScript ascolta eventi (pointermove, scroll, resize…)
- calcola valori
- li scrive in CSS custom properties
- CSS li usa per trasformazioni, gradienti, opacity, ecc.
Funziona, ma è facile finire con:
- molto boilerplate (listener, throttling, cleanup)
- logica duplicata per componente
- aggiornamenti continui anche quando l’elemento non è visibile
Props (for that) punta a risolvere esattamente questo: ti dà un modo dichiarativo per far arrivare a CSS una serie di valori “dinamici” (pointer, visibilità, viewport, FPS, velocità di scroll, ecc.) senza dover costruire tutta l’infrastruttura ogni volta.
L’idea: “JS conosce qualcosa, ora lo conosce anche CSS”
L’approccio è semplice: JavaScript si occupa di raccogliere segnali dall’ambiente (input, scroll, viewport…), e la libreria li espone come custom properties direttamente sugli elementi che lo richiedono.
Il cambio di paradigma non è tanto “posso fare un tilt con una riga”, ma:
- CSS diventa il posto dove compongo l’effetto
- JS diventa un provider di dati, non un orchestratore di animazioni
Questo è un passo importante perché ci permette di mantenere le animazioni e i look & feel in CSS (dove sono più facili da iterare), e usare JS solo per ciò che CSS non può misurare da solo.
Setup: import e dichiarazione per elemento
L’uso tipico parte da un import “auto” (che inizializza la libreria) e poi da un attributo HTML per dire quali props ti servono.
A livello concettuale:
- in JS importi l’entrypoint automatico
- in HTML aggiungi
data-props-forsull’elemento e elenchi le props
Esempio: vuoi tracciare il puntatore relativo a una card.
<article class="card" data-props-for="pointer local">
...
</article>
Da qui in poi, sull’elemento compariranno custom properties “live” come:
--live-local-pointer-x-ratio--live-local-pointer-y-ratio--live-local-pointer-inside
Valori “unitless” (ed è un vantaggio)
Un dettaglio furbo: i valori arrivano senza unità.
Sembra scomodo, ma è l’opposto: significa che puoi decidere tu come interpretarli.
- vuoi percentuali? moltiplichi per
100% - vuoi gradi? moltiplichi per
deg - vuoi pixel? moltiplichi per
1px
Questa neutralità rende le props molto riusabili.
Pointer-follow glow: gradienti che inseguono il mouse con puro CSS
Mettiamo che tu abbia un background con un radial-gradient e vuoi spostarne il centro in base al cursore.
In CSS:
.card {
--x: calc(var(--live-local-pointer-x-ratio, 0.5) * 100%);
--y: calc(var(--live-local-pointer-y-ratio, 0.5) * 100%);
background:
radial-gradient(circle at var(--x) var(--y), rgba(80, 140, 255, 0.6), transparent 55%),
#0b1020;
}
Punti chiave:
- i fallback (
0.5) tengono l’effetto stabile prima che i valori siano disponibili * 100%trasforma un rapporto 0..1 in una percentuale usabile inbackground-position- non hai scritto nessun listener
pointermovené aggiornato variabili a mano
Performance: traccia solo quando serve
La paura naturale è: “ok, ma se aggiorna tutto live, non mi ammazza le performance?”
La scelta progettuale interessante è che il tracking avviene solo quando l’elemento è rilevante, tipicamente quando è in viewport. Quando scorre fuori, smette di aggiornarsi.
Questo evita di buttare cicli CPU su elementi non visibili e rende l’approccio più scalabile su pagine lunghe con molte card.
Live vs Const: due famiglie di props per due tipi di animazioni
La libreria espone due categorie:
--live-*: valori continuamente aggiornati (es.--live-visible)--const-*: valori che cambiano “una volta” al verificarsi di un evento (es.--const-has-entered)
Esempio mentale: visibilità
--live-visible: passa da0a1quando entra in viewport, e torna a0quando esce--const-has-entered: parte da0, diventa1alla prima entrata, e resta1
Questa distinzione è utilissima:
- se vuoi un effetto che si resetta (entra/esce), usi
live - se vuoi un’animazione che parte una sola volta, usi
const
Reveal su scroll senza observer: opacity e twist controllati da una variabile
Con --live-visible puoi fare un reveal in modo quasi banale:
.twist-in {
opacity: var(--live-visible, 0);
transition: opacity 0.75s ease;
}
Se però vuoi un twist che “si annulla” quando diventa visibile, puoi invertire il valore:
.twist-in {
--is-offscreen: calc(1 - var(--live-visible, 0));
transform:
perspective(1000px)
rotateX(calc(var(--twist-x, -8deg) * var(--is-offscreen)))
rotateY(calc(var(--twist-y, -25deg) * var(--is-offscreen)));
transition: transform 0.75s ease;
}
Come funziona:
- quando
--live-visibleè0,--is-offscreenvale1→ la card è inclinata - quando
--live-visibleè1,--is-offscreenvale0→ le rotazioni vanno a zero
Alternare direzioni senza JS
Puoi personalizzare il verso del twist per singola card impostando solo due variabili:
<article class="card twist-in" style="--twist-y: 25deg; --twist-x: 8deg" data-props-for="visible">
...
</article>
Così eviti classi extra o logiche condizionali in JavaScript.
Quando usarla (e quando no)
Ha molto senso quando:
- vuoi far “guidare” a CSS trasformazioni/gradienti/filtri
- ti serve una fonte affidabile di valori ambientali (pointer, scroll velocity, viewport…)
- vuoi ridurre boilerplate di observer e listener
Potresti evitarla se:
- hai un caso ultra-specifico e preferisci una micro-utility ad hoc
- devi supportare ambienti dove non puoi aggiungere dipendenze
Sintesi: più dati a CSS, meno colla in JS
Props (for that) è interessante perché sposta l’equilibrio: invece di scrivere JS per orchestrare animazioni, scrivi CSS che reagisce a variabili già pronte. Il risultato è spesso più pulito, più modulare e, soprattutto, più facile da mantenere.
L’implicazione pratica è chiara: la prossima volta che stai per aggiungere l’ennesimo IntersectionObserver o l’ennesimo pointermove per aggiornare --mouse-x e --mouse-y, fermati un attimo e chiediti se non sia il caso di standardizzare quel flusso. Se CSS ha i dati giusti, molte interazioni diventano semplicemente… CSS.