Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Box con rollover e transizioni

Ottenere box o "tiles" animate sfruttando le transizioni CSS e il classico rollover. L'effetto è quello di una UI ricca di informazioni
Ottenere box o "tiles" animate sfruttando le transizioni CSS e il classico rollover. L'effetto è quello di una UI ricca di informazioni
Link copiato negli appunti

Prendendo spunto, tra i tanti siti che propongono l'effetto, dalla home page di Dribble, vedremo in questo articolo come creare dei box che mostrano un contenuto ausiliario con rollover e transizioni CSS3. Sarà un'occasione utile per mettere in pratica le transizioni stesse e per ragionare sul problema dell'hover sui dispositivi dotati di interfaccia touch. Iniziamo subito.

Rollover con transizioni: prima tecnica

Per rendere subito chiaro l'oggetto dell'articolo, possiamo partire dalla prima demo. Abbiamo una griglia con quattro box; ciascuno si presenta con l'immagine di un particolare tipo di sandwich; passando con il mouse sull'immagine viene rivelato un secondo box sovrapposto con il nome e gli ingredienti del sandwich.

Il markup HTML è estremamente intuitivo:

<div id="container">
   <div class="griglia">
     <div class="foto"><img src="1.jpg"></div>
     <div class="testo">
     <h1>Sandwich mediterraneo</h1>
     <h2>Ingredienti:</h2>
     <p>* lorem ipsum *</p>
     <p>* dolor sit amet *</p>
     <p>* consectetur *</p>
     <p>* adipisicing *</p>
     <p>* elit *</p>
     </div>
   </div>
   [...]
</div>

Un div contenitore e al suo interno quattro div con classe .griglia. Ciascuno di essi contiene un div con classe .foto destinato all'immagine del sandwich e un div con classe .testo per il contenuto testuale.

Per strutturare la griglia con i CSS abbiamo usato la tecnica basata su display: inline-block di cui abbiamo parlato in questo articolo:

div.griglia {
  border: 2px solid #fff;
  display: inline-block;
  width:  300px;
  height: 300px;
  margin: 10px;
  position: relative;
  overflow: hidden;
}

Da notare come sia stata dichiarata una position: relative: ci servirà dopo per posizionare assolutamente il div con il testo rispetto al suo contenitore.

Per il div con l'immagine l'unica regola di rilievo è quella con cui specifichiamo un display di tipo blocco per la foto:

div.foto img {
  display: block;
}

La parte più sostanziosa e importante per i nostri fini è quella del div per il testo. Analizziamo il tutto nei dettagli.

Per prima cosa assegniamo un colore per il testo e lo sfondo:

color: #fff;
background-color: #05418d;

Impostiamo poi le dimensioni (sono identiche a quelle del div.griglia!) e il padding:

width: 300px;
height: 300px;
padding: 10px;

Per far sì che le dimensioni siano quelle dichiarate, compreso il padding, specifichiamo la proprietà box-sizing in questo modo (si veda l'articolo Box model 'naturale' con border-box):

-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;

Come si vede nella demo, il box con il testo dovrà sovrapporsi perfettamente rispetto a quello con l'immagine. Dobbiamo quindi posizionarlo assolutamente rispetto all'elemento contenitore di entrambi, ovvero il div.griglia:

position: absolute;

Inizialmente, però, il div è 'nascosto', sarà solo sull'hover e dopo la transizione che apparirà sovrapposto. Pertanto impostiamo le coordinate di posizionamento così (abbiamo uno spostamento di 300px verso l'alto e 300px verso destra):

top: -300px;
left: 300px;

Impostiamo pure un livello iniziale di opacità pari a 0, che rende il div di fatto invisibile:

opacity: 0;

E ora la parte dedicata alla transizione (con l'uso dei prefissi proprietari per garantire il supporto sui vari browser):

-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;

Specificando la parola chiave all indichiamo che tutte le proprietà che definiamo vengono animate. La durata (transition-duration) è pari a mezzo secondo (0.5s). ease-in-out definisce la modalità di calcolo dei valori intermedi durante la transizione. Per un ripasso sulle transizioni CSS3, comunque, vi rimandiamo alla lezione ad esse dedicata della nostra guida.

La comparsa del div con il testo avviene passando con il mouse sul box, ovvero viene attivata nel CSS tramite :hover. Nel nostro caso l'hover va definito sul div.giglia, ma nella regola dobbiamo anche specificare che quanto inserito nella regola si applica al div.testo, quello che vogliamo animare con la transizione quando compare. Basta sfruttare al meglio i selettori e scrivere:

div.griglia:hover div.testo {
  opacity: 0.9;
  left: 0;
  top: 0;
}

Cosa abbiamo scritto? Più o meno questo: applica queste regole sul div.testo che è discendente del div.griglia in stato :hover. Oppure: quando il mouse passa sul div.griglia modifica queste proprietà del div.testo che è suo discendente.

Perché abbiamo appena detto 'modifica'? Perché a ben vedere stiamo impostando su nuovi valori proprietà già impostate per il div, come l'opacità e il posizionamento! E dunque, quando passiamo con il mouse sul box, l'opacità del div.testo si attesterà sul valore 0.9, lasciando che si intraveda in trasparenza la foto del sandwich. Lo stesso div andrà a posizionarsi sopra l'immagine (top: 0 e left: 0).

Figura 1 - Schema della transizione
screenshot

Avendo creato in precedenza la transizione, il passaggio avverrà con una bella animazione.

Una volta compreso il meccanismo di base e conoscendo le proprietà che è possibile animare, ci si può sbizzarrire con gli effetti.

Nella seconda demo abbiamo usato, ad esempio, le trasformazioni CSS3. Rimandiamo allo studio del codice per i dettagli.

Gli effetti di transizione possono peraltro essere applicati simultaneamente a diversi elementi che compongono un box (i titoli, il paragrafo, etc.) Per un campionario estremamente creativo segnaliamo questo esperimento di Codrops.

Rollover con transizioni: seconda tecnica

Un metodo alternativo per ottenere un effetto simile consiste nello sfruttare l'animazione della posizione dello sfondo e gli sfondi multipli. Ecco la terza demo.

Il markup HTML è leggermente diverso rispetto ai primi esempi:

<div class="griglia">
  <div class="testo">
    <h1>Sandwich mediterraneo</h1>
    <h2>Ingredienti:</h2>
    <p>* lorem ipsum *</p>
    <p>* dolor sit amet *</p>
    <p>* consectetur *</p>
    <p>* adipisicing *</p>
    <p>* elit *</p>
  </div>
  <div class="foto"></div>
</div>

In questo caso, il div.testo va definito nel codice prima del div.foto, il quale rimane vuoto.

Con i CSS andremo a impostare per quest'ultimo uno sfondo multiplo, usando però la stessa immagine. Una duplicazione che può sembrare assurda ma che serve per realizzare l'effetto:

div.foto {
  width: 300px;
  height: 300px;
  /* Sfondo multiplo con la stessa immagine */
  background-image: url('1.jpg'), url('1.jpg');
  background-repeat: no-repeat;
  /* Posizione iniziale degli sfondi */
  background-position: 0px 0px, 0px 0px;
  position: absolute;
  top: 0;
  left: 0;
  -webkit-transition: all 1s ease-in-out;
  -moz-transition: all 1s ease-in-out;
  -o-transition: all 1s ease-in-out;
  -ms-transition: all 1s ease-in-out;
  transition: all 1s ease-in-out;
  opacity: 1.0;
}

A parte le sezioni relative al posizionamento assoluto del div e alle transizioni (già viste), si noti la regola con cui impostiamo il posizionamento dei due sfondi. Inizialmente saranno di fatto sovrapposti e copriranno il div con il testo.

Cosa succede in stato :hover? Ecco:

div.foto:hover {
  background-position: -300px 0px, 300px 0;
  opacity: 0;
}

L'opacità passerà a 0 e gli sfondi saranno traslati il primo verso sinistra (-300px) e il secondo verso destra (300px), fino a scomparire. Abbiamo così animato l'uscita di scena delle due immagini/sfondo!

Con un po' di fantasia ci si può spingere oltre anche in questo caso. Nella quarta demo abbiamo usato ben quattro sfondi (ma sempre con la stessa immagine!):

div.foto {
  width: 300px;
  height: 300px;
  background-image: url('1.jpg'), url('1.jpg'),url('1.jpg'), url('1.jpg');
  background-repeat: no-repeat;
  background-position: 0px 0px, 0px 0px,0px 0px, 0px 0px;
  position: absolute;
  top: 0;
  left: 0;
  opacity: 1.0;
  -webkit-transition: all 1s ease-in-out;
  -moz-transition: all 1s ease-in-out;
  -o-transition: all 1s ease-in-out;
  -ms-transition: all 1s ease-in-out;
  transition: all 1s ease-in-out;
}

Sull'hover la prima si sposta verso sinistra, la seconda verso destra, la terza verso il basso; l'ultima rimane al suo posto ma trasparente:

div.foto:hover {
  background-position: -300px 0px, 0px 300px, 300px 0px, 0px 0px;
  opacity: 0.1;
}

Compatibilità cross-browser

Tutti gli esempi visti finora funzionano alla perfezione su Safari, Chrome e Firefox. Su Opera le transizioni sono supportate a partire dalla release 12.00. Su Internet Explorer lo saranno solo a partire dalla 10.00. Avendo testato su IE9, comunque, abbiamo verificato che a parte la transizione i contenuti sono pienamente fruibili. Su versioni precedenti del browser di Microsoft andrà anche valutata l'assenza di suuporto per la proprietà opacity.

:hover sui dispositivi touch

Come si vede, la potenza dei CSS3 consente di ottenere in poco tempo effetti accattivanti e anche efficaci a livello di esperienza utente. Il caso specifico, però, ci porta ad affrontare i problemi posti da questo tipo di interazioni sui dispositivi con interfaccia touch.

Sin dall'uscita dei primi iPhone, gli sviluppatori più attenti hanno evidenziato come su tali dispositivi il concetto stesso di :hover abbia poco o nessun senso. Qualcuno è arrivato a chiedersi se non si possa dichiarare del tutto estinto questo tipo di evento. In effetti, se passo con il mouse su un link presente su questa pagina, vedrò apparire la sottolineatura; se ci clicco sopra, vengo indirizzato su una nuova pagina. Su un iPad questa cosa, nei modi in cui l'abbiamo descritta, non è replicabile.

Senza scendere in dettagli molto complessi, si può sintetizzare il tutto con questa frase di Peter Paul Kock:

Il mouse è un dispositivo di puntamento continuo; il dito è discontinuo. E in questo sta tutta la differenza.

Il fatto che il tap che faccio su un tablet abbia quasi sempre gli stessi effetti del click che faccio con il mouse non deve insomma trarre in inganno, siamo in due mondi diversi. E nel mondo degli schermi touch non c'è hover, non ci sono equivalenti di eventi come mouseOver e mouseOut.

Sviluppando un sito, dunque, è doveroso accertarsi se gli effetti legati all'hover funzionano al meglio su dispositivi touch, soprattutto se tali interazioni servono a convogliare contenuti fondamentali. Se non vedo la sottolineatura sotto il link, tutto sommato la mia esperienza di utente non risulta menomata. Ma se passando il dito sulla foto del sandwich non vedo comparire gli ingredienti, è grave, perché non posso fruire di una parte cruciale del sito. Se il mio strepitoso menu attivato al passaggio del mouse non va, sono guai.

La soluzione? Rinunciare del tutto a questo tipo di effetti? Troppo drastico. Si possono per esempio prevedere dei meccanismi ispirati al responsive design e sfruttare le media query per servire ai dispositivi touch versioni alternative dell'interfaccia.

Risultati analoghi si possono ottenere attraverso librerie come Modernizr e in generale con Javascript.

Per esempio, preparate le demo per questo articolo, abbiamo verificato che la terza e la quarta non funzionano su iPad, così come non funzionano sul tablet di Apple le fantastiche sperimentazioni di Codrops che abbiamo segnalato prima. Cercando una soluzione in rete, ci siamo imbattuti prima su questo articolo.

Abbiamo implementato la tecnica nella quinta demo. Si tratta di un piccolo snippet di codice Javascript basato su jQuery tramite il quale possiamo associare ad un certo elemento l'evento click come alternativa all'hover definito nei CSS (in effetti non facciamo altro che emulare l'hover):

$(document).ready(function() {
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPad/i))) {
    $("div.foto").click(function(){
    });
}
});

Nella sesta demo, un approccio alternativo, sempre basato su jQuery:

$(document).ready(function() {
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPad/i))) {
    $("div.foto").bind("touchstart", function() {
      $(this).addClass("over");
    }).bind("touchend", function() {
      $(this).removeClass("over");
    });
}
});

Associamo al div.foto gli eventi touchstart (equivale a mousedown) e touchend (equivale a mouseup) per, rispettivamente, aggiungere e rimuovere la classe .over.

Nel CSS avremo dunque:

div.foto:hover, div.foto.over {
  background-position: -300px 0px, 0px 300px, 300px 0px, 0px 0px;
  opacity: 0.1;
}

Se provate ad eseguire le due demo su iPad potrete verificare un'altra cosa. Facendo tap sul box vengono sì applicate le transizioni, ma per tornare allo stato iniziale è necessario eseguire la stessa azione sul secondo box. Questo perchè sui dispositivi touch gli stili applicati con :hover vengono rimossi solo quando il focus si sposta su un altro elemento.

Per un approfondimento su questi temi consigliamo la lettura di questo PDF curato da Peter Paul Koch.

Tutti gli esempi sono come sempre disponibili in allegato.

Ti consigliamo anche