Come realizzare un Mobile Action Sheet con Bootstrap 3 e Animazioni CSS3
Nella realizzazione di HTML5 Mobile App in CSS3 e Javascript numerosi sono i controlli che possono essere ricreati in modo da sviluppare prodotti che si avvicinano più possibile alle applicazioni native.
Negli articoli precedenti mi sono soffermato più volte sull’importanza delle performance di animazioni CSS3 per quanto riguarda le interfacce web, soprattuto per quelle destinate a girare su dispositivi mobile.
Utilizzando questo tipo di animazioni, che forzano la creazione di livelli grafici da essere poi inviati alla GPU velocizzando il processo di rendering, è possibile riprodurre la maggior parte dei componenti presenti in app native in modo fluido e performante.
A questo proposito ti consiglio di leggere:
Con i CSS3 è possibile riprodurre per esempio elementi come slide menu (ecco un tutorial su come crearne uno), tab bar, modal alert, popover ecc..
Mobile Action Sheet con Animazioni CSS3
In questo articolo voglio mostrarti come realizzare un modal action-sheet sfruttando animazioni CSS3 performanti, che agiscono su determinati attributi in modo da sfruttare la tecnica della composizione dei livelli grafici.
In altre parole ricreeremo una modal dialog con dei pulsanti al suo interno che compare dal fondo dello schermo.
Per quanto riguarda gli stili dei pulsanti ci serviremo di quelli forniti dal framework Twitter Bootstrap 3, che con i suoi gruppi di pulsanti verticali si avvicina molto ai pulsanti che si trovano nel mobile action sheet del sistema operativo iOS7.
Qui a fianco uno screenshot che mostra il classico esempio di un mobile action sheet nativo durante l’utilizzo dall’applicazione “Mail” di iOS7
Il markup HTML
Dopo aver incluso nel documento le risorse di cui ci serviremo, come appunto il framework Twitter Bootstrap, Modernizr ed il solito jQuery, andiamo a definire il markup HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<nav> <!-- tabbar --> </nav> <article> <!-- corpo documento --> <h1>Action Sheet con animazioni CSS3</h1> <div class="text-center"> <button id="start" type="button" class="btn btn-default">Mostra action sheet</button> </div> </article> <div class="action-sheet"> <!-- contenitore action sheet --> <div></div> <!-- l'overlay dell'action-sheet --> <section> <!-- il contenitore dei pulsanti --> </section> </div> |
Oltre ai tag <nav> ed <article>, che rappresentano rispettivamente la tabbar ed il corpo del documento, inseriamo il codice HTML per definire gli elementi DOM che rappresentano l’intero action sheet. Abbiamo un contenitore principale (con classe .action-sheet) all’interno del quale si trovano una <div> ed un elemento <section>, il primo per l’overlay trasparente di sfondo, mentre il secondo per il contenitore dei pulsanti.
Vediamo ora come scrivere il markup dei pulsanti, utilizzando gli stili di Bootstrap:
1 2 3 4 5 6 7 8 9 10 11 12 |
<div class="row"> <div class="col-xs-12 col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3 btn-group-vertical"> <button type="button" class="btn btn-default">Pulsante 1</button> <button type="button" class="btn btn-default">Pulsante 1</button> <button type="button" class="btn btn-default">Pulsante 1</button> </div> </div> <div class="row"> <div class="col-xs-12 col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3"> <button type="button" class="btn btn-danger btn-block cancel">Chiudi</button> </div> </div> |
Abbiamo organizzato il gruppo di pulsanti in una prima <div> con classe .row, in modo da rendere poi responsive gli elementi interni utilizzando le classi del sistema a griglia di Bootstrap (piena larghezza nel caso di smartphone, 6 colonne centrate nel caso di tablet e dispositivi desktop).
Per riprodurre poi i pulsanti abbiamo utilizzato le solite classi .btn e .btn-[tipo-di-stile] al fine di definire quale tipo di pulsante utilizzare. Nel caso del gruppo di pulsanti superiore ci siamo serviti della classe .btn-group-vertical che come accennato in precedenza raggruppa verticalmente i pulsanti in modo molto analogo a quello di iOS7.
Il foglio di stile CSS3
Vediamo ora come servirci di animazioni CSS3 performanti per realizzare gli effetti desiderati.
Il primo effetto sarà applicato alla <div> che rappresenta l’overlay di sfondo, il quale dovrà apparire in dissolvenza, mentre il secondo sarà applicato al contenitore dei pulsanti (ovvero l’elemento <section>), che dovrà fare la sua comparsa dal fondo dello schermo.
Come prima cosa posizioniamo i due elementi utilizzando l’istruzione position:absolute e le relative coordinate:
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 |
.action-sheet { /* finchè non viene avviata l'animazione lasciamo la proprietà "display: none" in modo che l'elemento non vada ad interferire con il resto del DOM del documento (omettendo questa istruzione, questo elemento non sarebbe comunque visibile, ma allo stesso la sua presenza tempo non permetterebbe di interagire con gli altri elementi) */ display: none; } /*overlay di sfondo */ .action-sheet > div{ /* impostiamo le dimensioni e ed il posizionamento assoluto dell'overlay in modo da coprire tutto il documento */ position:absolute; top:0;right:0; left:0;bottom:0; /* per dare la trsparenza all'overlay utilizziamo l'attributo 'rgba' che ci permette appunto di impostare un valore di trasparenza */ background: rgba(0,0,0, 0.5); } /* contenitore pulsanti */ .action-sheet > section{ /* anche qui impostiamo il posizionamento assoluto in modo da poter facilmente posizionare il contenitore in fondo allo schermo */ position:absolute; left:0; right:0; bottom:0; background: none; padding: 0 10px; } |
Poi passiamo ad impostare il punto focale dell’esperimento, ovvero il funzionamento dell’effetto:
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 |
.action-sheet > div{ /* trasparenza iniziale pari a 0, in modo da visualizzare l'overlay in dissolvenza */ opacity:0; /* impostiamo l'effetto tramite la proprietà transition utilizzando l'opacity, attributo performante, per creare un effetto a comparsa sulla trasparenza */ -webkit-transition: opacity .15s; -moz-transition: opacity .15s; transition: opacity .15s; } /* contenitore pulsanti */ .action-sheet > section{ /* impostiamo la proprietà transitio per l'attributo "transform", che forza la creazine dei livelli grafici da inviare alla GPU e rende più fluida l'animazione */ -webkit-transition: -webkit-transform .3s; -moz-transition: -moz-transform .3s; transition: transform .3s; /* inzialmente impostiamo il la transform del contenitore in modo che prima dell'avvio dell'effetto si trovi al di fuori dello schermo, mediante il parametro "Y" della proprietà translate3d */ -webkit-transform: translate3d(0, 110%, 0); -moz-transform: translate3d(0, 110%, 0); transform: translate3d(0, 110%, 0); } |
Riassumento il discorso, per ricreare gli effetti abbiamo attribuito alla proprietà transition i parametri opacità (per l’overlay) e tranform (per il contenitore dei pulsanti) facendo in modo che quando essi vengono modificati, di conseguenza viene avviata anche l’animazione di comparsa. In particolare, andiamo a modificare quei parametri nel caso in cui alla div con classe .action-sheet presenti anche la classe di stile “open”.
(La div .action-sheet serve quindi solamente ad attivare in un colpo solo le animazioni applicate agli elementi che si trovano al suo interno.)
Il codice Javascript
Abbiamo detto che per attivare l’effetto dobbiamo solamente aggiungere la classe “open” alla div .action-sheet. Come al solito per farlo ci serviamo del Javascript e procediamo in questo modo:
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 |
/* Grazie a modernizr riprendo il nome dell'evento di fine animazione, che cambia a seconda del browser */ var endTransitionName = { 'WebkitTransition' : 'webkitTransitionEnd', 'OTransition' : 'oTransitionEnd', 'msTransition' : 'MSTransitionEnd', 'transition' : 'transitionend' }; var transitionEventName = endTransitionName[ Modernizr.prefixed( 'transition' ) ]; $(function(){ var actionSheet = $(".action-sheet"); $("#start").on("click", function(){ actionSheet.show(); //equivalente ad impostare la proprietà "display" = "block" setTimeout(function () { actionSheet.addClass("open"); //aggiungiamo la classe 'open' per avviare l'aniamzione }, 10); }); $(".cancel").on("click", function(){ //rimuoviamo la classe che scatena l'effetto, in modo da ritornare allo stato di partenza //all'evento di fine della transition reipostiamo tramite jQuery la propretà "display" = "none", //che era quella dello stato iniziale actionSheet.removeClass("open").one(transitionEventName, function () { actionSheet.hide(); }); }); }); |
Al click del pulsante con id “start” rendiamo visibile tutto il markup del nostro componente tramite il metodo .show() di jQuery (che equivale ad impostare la proprietà CSS “display: block” ), poi con un ritardo di 10 millisecondi (piccolo hack per “far passare qualche istante di il tempo” dopo il rendering del markup), aggiungiamo la classe “open“, avviando l’effetto a comparsa.
Al contrario, nel momento in cui l’utente effettua il click (o tap, se si tratta di mobile) sul pulsante di chiusura .cancel, rimuoviamo la classe “open” e, nel momento in cui l’animazione giunge al termine, reimpostiamo la proprietà “display: none” per la div .action-sheet, in modo da nasconderla di nuovo.
Come è possibile vedere dal codice, per riprendere il nome giusto dell’evento di fine animazione in base al browser utilizzato dall’utente, ci siamo serviti di Modernizr, ed in particolare del metodo .prefixed(”transition’).
Eccoci quindi al risultato finale: come puoi vedere il movimento risulta fluido e piacevole, anche se lo si visualizza da un dispositivo mobile.
Conclusioni
Con questo ennesimo esempio ti ho voluto dimostrare come sia possibile servirsi della composizione dei livelli grafici e dell’accelerazione hardware per sfruttare la GPU al fine di realizzare interfacce mobile, dove è possibile avere animazioni più lente e caratterizzate da numerosi sfarfalli, se non vengono utilizzate le giuste proprietà.
Per vedere la differenza tra un’animazione fluida ed una con sfarfallii, ti consiglio di provare la demo di questo tutorial in cui ho messo a confronto l’effetto di riempimento di due progressbar:
Crea la tua mobile app in HTML, CSS3 e Javascript
Utilizzando questa tecnica insieme a molte altre, ho realizzato più di 10 mobile app in HTML, CSS3 e Javascript (tra cui Tint e Dieta SI o NO?).
Se anche tu vuoi realizzare la tua applicazione in HTML, CSS e javascript da distribuire nei vari store, forse potrebbe interessarti il mio e-book HTML Mobile Accelerato.
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: Come realizzare un mobile action sheet con i CS...()