HTML Mobile App: animazione CSS3 su pagine di una lista
Nell’ultimo articolo ho spiegato come gestire gli eventi di fine animazione e fine transizione CSS3 tramite Modernizr, ottima tecnica per realizzare effetti performanti nella creazione di HTML Mobile App fluide e reattive.
In questo articolo, restando sempre nel tema delle HTML Mobile Apps, vedremo come combinare quella tecnica in combinazione con il framework animate.css, per realizzare una animazione css3 su pagine di una lista.
Forse ti potrebbe interessare: Animate.css: Raccolta di stili per animazioni CSS3 cross-browser.
Se sei un web designer interessato alla creazione di mobile app in HTML, CSS e Javascript, forse ti potrebbe interessare il mio e-book: HTML Mobile Accelerato, che spiega quali tecniche utilizzare per creare delle applicazioni fluide e altamente performanti, senza conoscere il codice nativo ma sfruttando solamente le tue conoscenze in ambito web.
L’idea è quella di creare la view di un’interfaccia mobile, contenente semplicemente un header ed una lista, alla quale applicheremo una paginazione tramite il click su due pulsanti “avanti” e “indietro“.
Il markup HTML
Come primo step impostiamo il markup HTML della pagina:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<nav> <button rel="prev"><i class="fa fa-chevron-left"></i> Indietro</button> <h1 class="title">HTML Mobile App</h1> <button rel="next">Avanti <i class="fa fa-chevron-right"></i></button> </nav> <article> <ul class='page animated'> <li class="show-detail"> <img src="img/1.jpg" height="80px"> <div> <h3>Lorem ipsum</h3> <h4>Radioactive</h4> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt.</p> </div> </li> <li class="show-detail"> <aside> <img src="img/2.jpg" height="80px"> </aside> <div> <h3>Lorem ipsum</h3> <h4>Radioactive</h4> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt.</p> </div> </li> ... ... ... </ul> </article> |
Dal codice possiamo vedere che il documento è molto semplice: abbiamo un header contenente i pulsanti “next” e “prev” per la paginazine, ed un tag article contenente la lista.
Siccome rappresenteremo ogni pagina con un elemento ul avente la classe ‘page‘, puoi ben notare che inizialmente sarà presente nel documento solo una pagina.
Gli stili CSS
Vediamo quali stili applicare alla pagina, al fine di ottimizzarne il layout per i dispositivi mobili
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
.page { list-style: none; margin: 0; padding: 0; border-top: solid 1px #c8c8c8; border-bottom: solid 1px #c8c8c8; background-color: #fff; overflow: hidden; overflow-y: auto; /* stili per il posizionamento */ position: absolute; top:100px; bottom:0; width: 100%; } /* stili per le pagine prima delle animazioni di entrata, 'nascoste' fuori dallo schermo, a sinistra nel caso della classe prev, a destra nel caso della classe next */ .page.prev{ -webkit-transform: translateX(-110%); -moz-transform: translateX(-110%); -o-transform: translateX(-110%); transform: translateX(-110%); } .page.next{ -webkit-transform: translateX(-110%); -moz-transform: translateX(-110%); -o-transform: translateX(-110%); transform: translateX(-110%); } |
In primis abbiamo attribuito gli stili alla lista, in modo da renderla più accattivante, poi ci siamo soffermati sulla parte più importante, il posizionamento.
Usiamo poi un position:absolute per poter spostare la pagina all’interno del documento; con l’attribuito width:100% diamo alla pagina la stessa larghezza della finestra, mentre con gli attributi top e bottom dettiamo la sua altezza rispetto a quella del documento.
Il risultato è un layout fluido ed ottimizzato per ogni risoluzione (prova a ridimensionare la finestra nella demo)
Impostiamo una proprietà transform: translateX(-110%) , con i vari prefissi per la compatibilità, ad ogni pagina avente classe ‘next‘ o ‘prev‘, in modo da “nascondere” fuori dallo schermo (rispettivamente a destra o a sinistra) la div creata al click dei pulsanti avanti e indietro, ma non ancora animata.
La libreria animate.css
Come già accennato, per animare le pagine ci serviamo delle due animazioni ‘slideInLeft’ e ‘slideInRight’ del framework CSS3 animate.css, per cui includiamo la libreria all’interno del tag head del documento (è possibile scaricare uno stilesheet custom dalla sezione custom build del sito):
1 |
<link href="css/animate-custom.css" rel="stylesheet"> |
Il codice Javascript
Includiamo come al solito jQuery nel documento. Visto che questo è soltanto un tutorial, per il rendering di ogni pagina successiva o precedente, ci limiteremo a clonare la pagina già esistente per poi inserire il nuovo elemento nel documento.
Ovviamente in un contesto reale (che presenti dati reali), l’operazione dovrebbe essere sostituita dalla generazione del markup tramite un sistema di javascript templating o altre logiche di codifica javascript in combinazione con dati (in formato json, xml ecc.) già precariati nella pagina, o magari caricati al click dei pulsanti “next” e “prev” tramite una chiamata Ajax.
Per prima cosa “ricaviamo” il nome dell’evento di fine animazione tramite Modernizr:
1 2 3 4 5 6 7 |
var endAnimationName = { 'WebkitAnimation' : 'webkitAnimationEnd', 'OAnimation' : 'oAnimationEnd', 'msAnimation' : 'MSAnimationEnd', 'animation' : 'animationend' }; var animationName = endAnimationName[ Modernizr.prefixed( 'animation' ) ]; |
Poi passiamo alla gestione dell’evento c’lick’ su entrambi i pulsanti di ‘next‘ e ‘previ‘:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
//variabile globale per controllare se un'animazione è in corso o meno var animating = false; //bind dell'evento click sui pulsanti di paginazione $("nav button").on("click", function(){ /* siccome non vogliamo che più animazioni vengano eseguite contemporanemante, annulliamo l'animazione se un 'altra è in corso. Con questa tecnica evitiamo per esempio l'avvio di due animazioni se l'utente effettua un doppio click sul pulsante */ if(animating) return false; /* riprendiamo come prima cosa il tipo di button (next o prev) attraverso l'attributo 'rel' */ var mode = $(this).attr("rel"); /* cloniamo l'elemnto della lista; questa azione, in un contesto reale, andrebbe sostituita con la generazione di una lista a dopo un'eventuale chiamata ajax per reperire i dati o qualunque altro sistema per ottenere idati della pagina successiva o precedente */ var newPage = $("ul.page").clone(); /* una volta generato l'elemento della lista, aggiungiamo la classe next o prev, a seconda button premuto; questa classe determinerà la posizione della pagina prima dell'animazione (fuori dello schermo, a sinistra o a destra). */ newPage.addClass(mode) //aggiungiamo l'elemento DOM al documento, all'interno del tag article $("article").append(newPage); /* a seconda del tipo di button premuto aggiungiamo la classe di entrata da destra o sinista, che avvia l'animazione */ animating = true; //l'animazione ha inizio newPage.addClass(mode=="next"?"slideInRight":"slideInLeft"); /* gestiamo l'evento di fine animazione in modo da resettare la variabile 'animating' e rimuovere l'elemento precedente dal documento, per alleggerire il markup (utile nei dispositivi mobile) rimuoviamo inoltre le classi 'next' o 'prev' e 'slideInRight' o 'slideInLeft' dall'elemento */ newPage.one(animationName, function(){ animating = false; $("ul.page").not(newPage).remove(); newPage.removeClass("next prev slideInRight slideInLeft"); }); }); |
Dal codice puoi vedere che ho utilizzato lo stesso selettore per selezionare i pulsanti su cui gestire l’evento di click, in quanto le azioni da svolgere per entrambi sono le stesse, a parte la differenza della classe CSS che detta il tipo di animazione di entrata nello schermo (slideInLeft o slideInRight).
Un aspetto da sottolineare è il fatto che la pagina precedentemente visualizzata viene rimossa dal documento alla fine dell’animazione di quella appena creata: ciò è pensato per alleggerire il markup su cui un eventuale dispositivo mobile dovrebbe eseguire il rendering.
Nel possibile scenario di un’app il cui compito è quello di mostrare un elevato numero di record all’interno di una lista paginata, dopo aver scorso qualche decina di pagine, l’utente potrebbe assistere infatti ad un improvviso arresto (o crash), dovuto all’elevato numero di elementi DOM su cui il browser sarebbe costretto ad eseguire il rendering.
Il risultato finale
Il gioco è fatto! Dalla demo si può notare come applicando poche righe di codice Javascript e facendo svolgere quasi tutto il lavoro ai CSS3 tramite delle animazioni performanti, è possibile realizzare interfacce che non hanno nulla da invidiare a quelle di applicazioni native (hai notato l’ottima fluidità dell’animazione di entrata di ogni pagina?).
Crea la tua mobile app in HTML, CSS3 e Javascript
Utilizzando questa tecnica unita a molte altre ho creato per i miei clienti oltre 10 applicazioni per dispositivi mobile, tra cui due progetti personali: Tint Weather App e Dieta SI o NO?. Se anche tu sei un web designer e vuoi realizzare la tua applicazione mobile da distribuire nei vari stores, forse sarai interessato al mio e-book: HTML Mobile Accelerato.
Grazie ad esso verrai a conoscenza di tutte quelle tecniche che renderanno la tua applicazione mobile fluida e reattiva come quelle native.
Giacomo Freddi
Web Designer Freelance e Developer, si occupa del design e dello sviluppo di applicazioni web dal 2008, come molti freelance è abituato a gestire più ruoli e spaziare su più campi, ma la sua passione principale è quella della creazione di interfacce front-end e back-end utilizzando codice html5 e css3. Adora usare pattern MVC per i suoi Javascript.
Pingback: HTML Mobile App: animazione CSS3 su pagine di u...()
Pingback: HTML Mobile App: animazione CSS3 su pagine di una lista | Laboratorio CSS()