Realizzare un calendario dell’avvento con HTML, CSS(3) e (poco) Javascript

Come realizzare un calendario in html, css e jsQuesto articolo è un semplice tutorial che approfondisce alcune tecniche utilizzate per la realizzazione del calendario dell’avvento online realizzato da Nea Mesa Comunicazione.
In particolare abbiamo trattato, in forma di esempio pratico, le possibilità offerte nei moduli transforms e transitions nelle specifiche CSS.Negli esempi CSS, per semplificarne la leggibilità, abbiamo indicato solo le proprietà “pure”, tralasciando le istruzioni con prefisso (Vendor prefix su Wikipedia).
La fonte principale di informazioni utilizzata è Mozilla Developer Network, ma in rete si possono trovare molti ottimi articoli, tutorial e corsi.
Il calendario è compatibile con i browser più moderni, con qualche accorgimento per renderlo funzionante anche su Internet Explorer 10.
La tabella delle compatibilità è disponibile qui, in chiusura dell’articolo.

Il layout

Iniziamo impostando la grafica del nostro calendario, creando cioè due immagini che dovranno sovrapporsi l’una all’altra.

calendario1

Fig1. – Le finestre “chiuse”.
calendario2

Fig2. – Le finestre “aperte”.

Poi con l’ausilio di un buon programma di manipolazione delle immagini, taglieremo in 25 pezzi, uno per giorno, il calendario.
Naturalmente le immagini che si sovrappongono dovranno essere della stessa misura.

La finestra del giorno

Iniziamo impostando il codice html che definirà una ad una tutte le finestre del calendario:

<div class="container"><!-- il contenitore che flotterà-->
	<div class="giorno" title="01"><!--la finestra del giorno-->
    <img class="cover" src="cover/01.jpg" alt="1"/><!--l'immagine "nascosta"-->
    <img class="flip" src="flip/01.jpg" alt="1"/><!--l'immagine visibile-->
    </div>
</div>

Il primo div (.container) ci servirà per disporre le finestre una a fianco all’altra.
Nel secondo div (.giorno) sono contenute le immagini.
Il foglio di stile imposterà tutte le caratteristiche necessarie:

	
	.container {
		float: left;
		height: 160px;
		margin: 5px;
		position: relative;
		width: 160px;
		}
	
	.giorno {
	    	cursor: pointer;
	    	height: 100%;
	    	left: 0px;
	    	position: absolute;
	    	top: 0px;
	    	width: 100%;
		}
		
	.giorno img {
	    	border-color: #770000 #f00 #f00 #770000;
	    	border-style: solid;
	    	border-width: 1px;
	    	height: 100%;
	    	left:0px;
	    	position: absolute;
	    	top:0px;
	    	width: 100%;
		}

Come si noterà le immagini sono posizionate in modo assoluto sulle stesse coordinate (0 , 0).
Così facendo l’immagine .flip “coprirà” l’immagine .cover, nascondendola.
L’istruzione float:left applicata al contenitore alineerà le finestre, ponendole una di fianco all’altra.

Montiamo il calendario

Ora non resta che replicare per altre 24 volte lo stesso codice html, modificando, ovviamente, i path delle immagini.
L’intero blocco delle 25 finestre sarà rinchiuso in unico div (#calendario) al quale daremo una larghezza tale da distribuire le finestre in file di cinque ovvero 170px (160 di larghezza + 10 dei margini) X 5 = 850px.

<div id="calendario">

  <div class="container"><!-- il contenitore che flotterà-->
    <div class="giorno"><!--la finestra del giorno-->
      <img class="cover" src="cover/01.jpg" alt="1"/><!--l'immagine "nascosta"-->
      <img class="flip" src="flip/01.jpg" alt="1"/><!--l'immagine visibile-->	
  </div>

  <div class="container"><!-- il contenitore che flotterà-->
    <div class="giorno"><!--la finestra del giorno-->
     <img class="cover" src="cover/02.jpg" alt="2"/><!--l'immagine "nascosta"-->
     <img class="flip" src="flip/02.jpg" alt="2"/><!--l'immagine visibile-->
  </div>

		... ecc. ...

</div>

Apriamo le finestre. La proprietà transform.

Il calendario è montato: ora con un po’di css e un tocco di javascript possiamo rendere “apribili” le finestre.
Per farlo useremo due proprietà CSS: transform e transition. Per facilitare la lettura non abbiamo inserito negli esempi le istruzioni con prefisso (-webkit- , -moz-), ma solo la versione “pura”.
Ecco come si presenta la sezione del foglio di stile dedicata alle finestre con le nuove istruzioni e una nuova classe, .flipped che sarà aggiunta o rimossa dinamicamente – per mezzo di javascript – al div.giorno. Per effetto della contestualità, la presenza di questa classe cambierà lo stato dell’immagine.

.giorno {
	cursor: pointer;
	height: 100%;
	left: 5px;
	position: absolute;
	top: 5px;
	perspective: 920px;
	width: 100%;
	}
	
.giorno img { 
	backface-visibility: hidden;
	border-color: #770000 #f00 #f00 #770000;
	border-style: solid;
	border-width: 1px;
	height: 100%;
	left:0;
	position: absolute;
	top:0;
	transition: transform 1.0s;
	width: 100%;
	}

.flip{ 
	transform: rotateY(0deg); 
	}

.cover{ 
	transform: rotateY(-180deg); 
	}
 
.flipped .flip{
	tranform: rotateY(180deg);
	}
	
.flipped .cover{
	transform: rotateY(0deg);
	}
   

Per mezzo dell’istruzione rotateY il css opera una trasformazione sugli elementi immagine, ruotandoli sul loro asse verticale (Y).
All’apertura della pagina .flip non è di fatto ruotato, rotateY(0deg); .cover, invece, è ruotato sullo stesso asse di 180°, rotateY(-180deg);

.flip non è ruotato: rotateY(0deg);

.cover è ruotato di 180°: rotateY(-180deg);

Quando al div.giorno è aggiunta la classe .flipped la situazione si inverte: .flip ruota di 180°, rotateY(180deg); .cover ruota per tornare ad una visualizzazione normale: rotateY(0deg).

.flip ruota di 180°: rotateY(180deg);

.cover è ruotato di 180°: rotateY(0deg);

Queste poche rige di javascript consentiranno di aggiungere (o togliere se c’è già) la classe .flipped al div.giorno. Lo script si appoggia JQuery, ma naturalmente l’uso di questa libreria è puramente indicativo.
In ogni caso, se decidete di usare JQuery non dimenticate di caricarlo nella pagina…

	
$('.giorno').each(function(){
	$(this).click(function(){
		$(this).toggleClass('flipped');
	});
});	

Pur operando nella realtà bidimensionale dello schermo le proprietà come rotateY ci trasportano di fatto in un contesto 3D. In tale contesto un elemento ha anche una “faccia posteriore” che nel nostro caso deve essere nascosta. Questo spiega l’uso della proprietà backface-visibility valorizzata a hidden.

Il contesto tridimensionale ci permette anche di applicare effetti prospettici agli elementi ruotati con la proprietà perspective.

perspective: 920px

In questo modo durante la rotazione l’immagine sembra veramente “fuoriuscire” dal proprio contenitore.
Da notare che la deformazione prospettica sarà tanto più accentuata quanto più piccolo è il valore di perspective (nell’esempio seguente indicato a 320px;). Nel contesto tridimensionale nel quale agisce la proprietà “esiste” un piano di fondo (Z) la cui profondità è definita dal valore di perspective. La deformazione prospettica dell’oggetto è inversamente proporzionale a questo valore . Poiché rappresenta la distanza tra lo spettatore e l’oggetto, maggiore è il valore meno intenso è l’effetto visivo.
Per definizione il punto di fuga è posto al centro dell’oggetto: la proprietà perspective-origin permette di controllarne la posizione sugli assi verticale e orizzontale.

perspective: 320px
perspective-origin:10% 90%

Animiamo l’apertura. La proprietà transition

Normalmente, quando il valore di una proprietà CSS cambia, il risultato della trasformazione (per esempio di uno sfondo da un colore a un altro) avviene immediatamente.
La proprietà transition permette di animare il passaggio di un elemento da uno stato ad un altro in modo fluido in un intervallo di tempo definito.
Per farla più semplice: senza transition (nel css applicata alle immagini oggetto di trasformazione), il passaggio da un’immagine all’altra avverrebbe instantaneamente, senza alcun effetto di rotazione.
Alle immagini da trasformare è associata l’istruzione transition: transform 1.0s; La proprietà è usata in modalità shorthand; il primo valore indica l’istruzione che deve essere animata (transform), il secondo valore la durata dell’animazione. Possono essere specificati anche i valori di ritardo (delay) nella partenza dell’animazione e la curva di velocità (transition-timing-function).

Teniamo a bada i curiosi?

Quando si possiede un calendario dell’avvento, si sa, non si dovrebero aprire le finestrelle se non nel giorno corrispondente. Se proprio vogliamo tenere sotto controllo i curiosi possiamo aggiungere nello script un meccanismo di controllo che impedisca l’interazione sulle finestre se la loro data non è uguale o precedente a quella odierna. I metodi per farlo sono diversi e ognuno può scegliere quello che preferisce.

In ogni caso, se volete vedere il calendario in azione e sbirciare nel codice, eccolo qua: http://neamesa.it/avvento/html/calendario-avvento-2016.html

Compatibilità con i principali browser

Fonte: Mozilla Developer Network

transform (3d)
Chrome Firefox IE Opera Safari
12.0 -webkit 10.0 -moz 10.0 15 -webkit 4.0 -webkit
36 16.0 23
transition
Chrome Firefox IE Opera Safari
1.0 -webkit 4.0 -moz 10.0 10.1 -o 3.0 -webkit
26.0 16.0 12.10 6.1
backface-visibility
Chrome Firefox IE Opera Safari
12 -webkit 10 -moz 10 15 -webkit -webkit
16
perspective
Chrome Firefox IE Opera Safari
12 -webkit 10 -moz 10 15 -webkit -webkit
45 16

Fabio Bosso
Nea Mesa Comunicazione

Lascia una risposta

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>