Fra i fautori della rinascita di JavaScript come linguaggio frontend si possono senza dubbio annoverare le librerie di animazione come moo.fx e script.aculo.us. Grazie alla loro introduzione, oggi è molto semplice aggiungere dinamicità alle pagine web senza dover ricorrere a plugin come Flash.
Negli ultimi periodi, tuttavia, si sta facendo strada una tecnica che delega gli effetti di transizione ai nuovi moduli CSS3 transitions e transforms, ormai largamente supportati dalle ultime versioni dei browser principali.
Il vero problema derivante dall'uso di queste proprietà CSS sta nel fatto che, essendo direttamente cablate nel codice, non offrono la flessibilità e l'adattabilità delle librerie JavaScript. Fortunatamente, però; ognuna delle proprietà CSS per regolare transizioni e trasformazioni è rintracciabile nella proprietà style
degli elementi del DOM.
Perché usare i CSS per le animazioni
Per molti versi, i moduli CSS3 dedicati alle animazioni svolgono le stesse operazioni di una libreria JavaScript, ma in modo nativo. Ne conseguono:
- un minor dispendio di memoria rispetto ad altre soluzioni
- un minor peso delle pagine web, visto che potremo far a meno di includere librerie JavaScript di effetti.
L'altra faccia della medaglia è che molto probabilmente sarà necessario cambiare il modo di sviluppare e progettare il frontend di un sito: mancando il supporto a questi moduli nelle vecchie versioni dei browser ed in IE, dovremo iniziare a pensare in termini di Progressive Enhancement, oppure dovremo prevedere una soluzione alternativa per i browser meno evoluti.
Per iniziare, potremmo realizzare in CSS solo gli effetti secondari, affidandoci a JavaScript per tutte le animazioni fondamentali (ed in un'interfaccia web solo poche lo sono veramente).
Transizioni CSS via JavaScript
Tutte le proprietà del modulo CSS3 Transitions sono rintracciabili e modificabili a partire dalla proprietà style
di un nodo del DOM. Come sempre dovremo utilizzare una notazione CamelCase:
/* CSS */
-webkit-transition-property: 'height';
/* JavaScript */
nodo.style.WebkitTransitionProperty = 'height';
Naturalmente, come in altri casi, possiamo impostare più propertà attraverso shortcode specifici:
/* JavaScript */
//proprietà, durata e andamento
nodo.style.WebkitTransition = 'height 200ms ease-in-out';
Prefissi
Come per i fogli di stile, anche in JavaScript le proprietà di transizione devono essere precedute dal prefisso del produttore del browser per essere riconosciute dal motore di rendering. Poiché le proprietà con prefissi non riconosciuti vengono scartate senza dare errore, possiamo allargare il supporto dei nostri script preservandone la funzionalità:
var nodo = document.getElementById('mioNodo'),
style = nodo.style,
value = 'height';
// Safari >= 3.2, Chrome >= 6
style.WebkitTransitionProperty = value;
// Firefox >= 4
style.MozTransitionProperty = value;
// Opera >= 10.50
style.OTransitionProperty = value;
// IE >= 9
style.msTransitionProperty = value;
// altri browser KHTML
style.KhtmlTransitionProperty = value;
// in vista di un futuro senza
// prefissi!
style.transitionProperty = value;
Per semplicità, in questo articolo immagineremo di lavorare in ambiente Webkit, mentre per approfondire le tematiche legate alle transizioni CSS potete fare riferimento a questo articolo.
Eventi
Oltre ad impostare le proprietà di una transizione, è possibile associarvi una funzione da lanciare alla fine, replicando così il funzionamento di molte librerie JavaScript. L'evento cui agganciare la funzione è transitionend
con due varianti proprietarie implementate da Webkit e Opera, rispettivamente webkitTransitionEnd
e oTransitionEnd
:
nodo.addEventListener('transitionend', function () {
alert('Transizione finita!');
}, false);
Ecco un esempio pratico di transizione dinamica con funzione di callback (da visualizzare con Chrome/Safari).
Link utili
Trasformazioni CSS con JavaScript
Le trasformazioni CSS sono un potente strumento per manipolare gli elementi di una pagina bypassando i limiti finora imposti dai browser. La possibilità di ruotare, distorcere e traslare un elemento con poche righe di CSS ci libera da librerie e script JavaScript spesso troppo pesanti per la CPU.
Inoltre, il sempre più diffuso supporto alle trasformazioni 3D apre nuovi campi di sperimentazione per gli sviluppatori frontend.
In JavaScript possiamo manipolare le proprietà delle trasformazioni a partire dall'oggetto style
, sempre tenendo conto dei prefissi vendor richiesti dai vari browser:
//ruoto un elemento di 45 gradi
nodo.style.WebkitTransform = 'rotate(45deg)';
Escludendo IE, la maggior parte dei browser moderni supportano le trasformazioni CSS ed è quindi una buona idea utilizzarle, insieme alle transizioni, al posto degli effetti JavaScript per alleggerire la CPU e diminuire la memoria occupata dalla pagina. Ecco un esempio pratico (da visualizzare con Chrome o Safari).
Per un'introduzione alle trasformazioni CSS potete fare riferimenti a questo articolo di Simone d'Amico.
Trasformazioni 3D
Introdotte di recente ed ancora poco supportate dai browser (al momento solo su Safari), le trasformazioni 3D aggiungono un terzo asse per la trasformazione degli elementi, offrendo la possibilità di giocare con le prospettive per donare profondità alle pagine web.
La caratteristica fondamentale di queste proprietà CSS è che, almeno nell'implementazione attuale, il rendering degli elementi trasformati è gestito direttamente dal motore 3D della scheda grafica. A parte il consueto risparmio di risorse ne consegue anche una notevole fluidità anche su sistemi poco potenti.
Transizioni, trasformazioni e dispositivi mobili
Un campo in cui gli sviluppatori hanno largamente sperimentato i moduli di animazione CSS è quello del mobile, soprattutto per l'impatto in termini di performance delle librerie JavaScript su CPU poco potenti e RAM ridotta.
Inoltre, la presenza di supporto alle trasformazioni 3D nelle versioni mobile dei browser per iPhone e Android ha permesso di delegare l'animazione alla GPU del device, garantendo una fluidità ed una reattività paragonabili a quelle di un'applicazione nativa.
Nonostante ciò, in alcuni casi l'uso di librerie JavaScript garantisce animazioni più fluide, soprattutto con transizioni concorrenti e in situazioni in cui l'uso delle trasformazioni CSS 2D e 3D non sia possibile.
Supporto dei browser
Uno dei problemi maggiori legati all'uso delle animazioni CSS è il supporto del browser dell'utente, oltre alla determinazioni del giusto prefisso da utilizzare.
Volendo andare sul sicuro potremmo affidarci a librerie specifiche di features detection come Modernizr:
<script type="text/javascript" src="modernizr.js"></script>
<script type="text/javascript">
if (Modernizr.csstransforms3d) {
// trasformazione 3D
} else if (Modernizr.csstransforms) {
// trasformazione 2D
} else {
// effetto JavaScript
}
</script>
Potremmo inoltre realizzare una funzione per applicare il giusto prefisso del vendor senza doverli applicare tutti per ogni animazione:
<script type="text/javascript">
var setTransition = (function () {
var test = document.createElement('div'),
prefissi = 'Webkit Moz O ms Khtml'.split(' '),
i = prefissi.length,
prefisso = null,
testTrans = 'TransitionProperty',
resultTrans = 'Transition';
//ciclo tutte le proprietà
while (i--) {
if( test.style[prefissi[i] + testTrans] !== undefined ) {
prefisso = prefissi[i];
}
}
if (prefisso) {
resultTrans = prefisso + resultTrans;
} else {
resultTrans = resultTrans.toLowerCase();
}
//cancello test per liberare memoria
test = null;
return function (node, transition) {
return node.style[resultTrans] = transition;
};
})();
//applico una transizione ad un elemento
window.onload = function () {
var mioEl = document.getElementById('mioEl');
setTransition(mioEl, 'left 1ms ease-out');
};
</script>
Risorse utili
Ecco alcuni risorse utili per approfondire la tematiche legate all'uso di animazioni CSS con (e senza) JavaScript: