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

Uno slideshow responsive con flexbox

Creiamo una galleria con immagini che si alternano con transizioni in fade e una dot navigation ( menu "a pallini") posizionata sopra la slide.
Creiamo una galleria con immagini che si alternano con transizioni in fade e una dot navigation ( menu "a pallini") posizionata sopra la slide.
Link copiato negli appunti

Siamo indecisi su quale componente esterno usare per aggiungere uno slideshow del nostro sito responsive? Vogliamo approfondire le potenzialità offerte da flexbox? Abbiamo almeno due valide ragioni per lavorare al progetto che stiamo per esaminare.

È vero che ci sono molti tipi di slideshow disponibili come widget di famosi frameworks di UI, tuttavia se non abbiamo bisogno di features particolari possiamo realizzarne uno piuttosto rapidamente sfruttando flexbox e poche righe di JavaScript.

In questo modo evitiamo di:

  • importare il codice necessario aumentando il peso della pagina;
  • investire tempo (anche minimo) nella comprensione di come utilizzare il plugin;
  • avere un controllo ridotto sul comportamento;
  • avere molto più di quanto ci si serve in termini di features, classi e codice in generale;
  • dover ricorrere probabilmente a sovrascritture o modifiche per la customizzazione.

Slideshow... sì ma come?

Tra i tanti tipi di slideshow, scegliamo uno dei più classici ed efficaci: la galleria con immagini che si alternano con transizioni in fade e una dot navigation ( menu "a pallini") posizionata sopra la slide.

Gestiremo il funzionamento dello slideshow interamente con i fogli di stile utilizzando una classe “active” sul pallino di navigazione e sulla slide selezionata per mostrarla. JavaScript si occuperà solo di assegnare e rimuovere la classe. Sfrutteremo flexbox per fare le slides e la navigazione.

Il flexbox layout è utilissimo per la realizzazione di componenti con elementi che vanno allineati piuttosto che per layout di pagina, a causa del minore controllo che ci mette a disposizione.

Con flexbox possiamo infatti ovviare ai limiti dei display ad orientamento monodirezionale (verticale con il display block, orizzontale con il display inline). Piuttosto dell'esatta posizione degli elementi al pixel viene data priorità alla loro distribuzione all'interno di un determinato spazio, definito dal flex container.

In uno scenario di compatibilità con i dispositivi mobili senza alcuna risoluzione di riferimento i pixel sono un'informazione sempre più marginale ed è necessario un approccio mobile-first. Flexbox ci aiuta proprio nell'implementazione del nostro design responsivo.

Il markup HTML dello slideshow

Come primo step, creiamo la struttura HTML del nel nostro slideshow. Per simulare in maniera realistica il risultato finale, lo creeremo all'interno di un div container responsive con larghezza in percentuale ed una max-width per desktop.

Inseriamo un div container dedicato allo slideshow che contiene una lista con le slides e una lista con i pallini per la navigazione. Dentro la lista delle slides mettiamo come primo item un'immagine placeholder, che serve per determinare l'ingombro totale della slide.

NOTA: L'immagine del placeholder così come tutte le immagini dello slideshow devono avere la stessa aspect ratio (16:9, 4:3, ecc…).

<div class="container">
	<h1>Flexbox Slideshow</h1>
    <div class="flexbox-slideshow">
		<ul class="slideshow">
			<li class="placeholder">
			  <img src="https://www.html.it/wp-content/uploads/2016/10/slide_flexbox_placeholder.jpg">
			</li>
			<li class="slide active" id="slide-1"><!-- ... --></li>
			<li class="slide" id="slide-2"><!-- ... --></li>
			<li class="slide" id="slide-3"><!-- ... --></li>
			<li class="slide" id="slide-4"><!-- ... --></li>
			<li class="slide" id="slide-5"><!-- ... --></li>
		</ul>
		<ul class="dotnav">
			<li class="dotnav-item active" onclick="changeOrder(this, 1)"><span></span></li>
			<li class="dotnav-item" onclick="changeOrder(this, 2)"><span></span></li>
			<li class="dotnav-item" onclick="changeOrder(this, 3)"><span></span></li>
			<li class="dotnav-item" onclick="changeOrder(this, 4)"><span></span></li>
			<li class="dotnav-item" onclick="changeOrder(this, 5)"><span></span></li>
		</ul>
	</div>
 </div>

Ogni slide contiene un'immagine e 2 caption, uno per il titolo della foto l'altro per l'autore. Alla prima slide e al primo pallino impostiamo la classe active.

<li class="slide active" id="slide-1">
	<img src="https://www.html.it/wp-content/uploads/2016/10/slide_flexbox_moon-1.jpg">
	<div class="caption-container">
		<div class="caption caption-title">
			<h2>Great caption about the moonlight</h2>
		</div>
		<div class="caption caption-author">
			<span class="author">John Doe</span>
		</div>
	</div>
</li>

CSS, struttura slideshow

Abbiamo scelto come transizione il fade e quindi le slides <li> sono posizionate una sopra all'altra con posizione assoluta rispetto alla lista <ul> che deve avere position relative dichiarata.

L'elemento della lista che contiene il placeholder è l'unico con position static di default e resterà sempre sotto le slides. Per mostrare la slide attiva con la classe aggiuntiva “active” cambieremo lo z-index mentre per l'effetto fade con le CSS transitions cambieremo l'opacità della sua immagine. Le immagini diventano responsive impostando la larghezza al 100%.

.flexbox-slideshow {
  position: relative;
  overflow: hidden;
}
.slideshow {
  padding: 0;
  margin: 0;
  list-style: none;
}
.slideshow li:not(.placeholder) {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
}
.slideshow li img {
  width: 100%;
  max-width: 100%;
  display: block;
  opacity: 0;
}
.slideshow li.active {
  z-index: 2;
}
.slideshow li.active img {
  opacity: 1;
}

CSS flexbox, le slides

Con flexbox vogliamo gestire i due caption dell'immagine in maniera veloce, senza doverli posizionare gestendo pixel e margini. Li vogliamo centrare verticalmente rispetto all'immagine ed allinearli alla sua sinistra, in modo tale da poterli animare in ingresso ed in uscita. Vogliamo inoltre distribuirli in maniera uniforme nello spazio disponibile. Inoltre i due caption contengono dei testi che in un sito responsive, a seconda della risoluzione, possono diventare multilinea ed avere quindi un ingombro diverso.

Come sappiamo, allineare verticalmente gli elementi non è mai stato immediato con i CSS ma con flexbox è facilissimo. Innanzitutto gestiamo la grandezza del container dei caption in modo tale che occupi lo stesso spazio dell'immagine e poi facciamolo diventare un flex container scrivendo display: flex. Ora tutti i nodi figli diretti sono flex-items, nel nostro caso il caption del titolo e il caption dell'autore.

Con le altre proprietà del div .caption-container stabiliamo come allineare i suoi flex-items. Poiché vogliamo che il caption dell'autore sia sotto quello del titolo scriviamo

flex-direction: column

per indicare che la direzione (asse principale) su cui si disporranno i flex-items è verticale. Con:

justify-content: center

diciamo al flex-container di disporre i flex-items al centro del suo asse principale permettendoci quindi di centrarli verticalmente. Infine:

align-items: flex-start

allinea i flex-items all'inizio dell'asse secondario o meglio trasversale (quindi nel nostro caso orizzontale) cioè a sinistra.

A questo punto possiamo animare i caption etichettati con la classe active (+ CSS transitions) cambiando il loro margine sinistro per farle entrare ed uscire sull'immagine attiva.

.slideshow li .caption-container {
  position: absolute;
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap;
  flex-direction: column;
}
.slideshow li .caption {
  background: rgba(0, 0, 0, 0.5);
  color: #f2f2f2;
  padding: 10px 20px;
  margin-left: -100%;
}
.slideshow li .caption.caption-title {
  margin-bottom: 10px;
  transition: all .2s ease;
}
.slideshow li .caption.caption-title > * {
  margin: 0;
}
.slideshow li.active .caption {
  margin-left: 0;
}

È importante notare come usando flexbox non dobbiamo dare altezze, larghezze in pixel, margini, posizionamenti puntuali e questo è perfetto per lo sviluppo responsive.

CSS flexbox, menu di navigazione a pallini

Per gestire il menu di navigazione usiamo lo stesso approccio facendo diventare la lista <ul> .dotnav un flex-container con display: flex ed allineando i flex-items cioè i pallini in basso al centro della slide impostando justify-content: center e align-items: flex-end.

In questo caso non impostiamo la flex-direction perché usiamo quella di default che è row. Justify-content lavora sull'asse principale, quindi impostare il valore center centra gli elementi in orizzontale se la flex-direction è row (default) e in verticale se la flex-direction è column (come nel caso precedente del .caption-container). Stesso discorso per la proprietà align-items solo applicato all'asse trasversale. Sempre con la classe active stiliamo il pallino relativo alla slide attiva.

.dotnav {
  position: absolute;
  list-style: none;
  padding: 20px;
  margin: 0;
  top: 0;
  width: 100%;
  z-index: 100;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  flex-wrap: wrap;
  height: 100%;
}
.dotnav li span {
  border-radius: 50%;
  display: block;
  height: 20px;
  width: 20px;
  margin-right: 20px;
  background: rgba(255, 255, 255, 0.3);
  cursor: pointer;
  box-shadow: 0px 1px 6px #000;
}
.dotnav li.active span {
  background: rgba(255, 255, 255, 0.5);
  cursor: default;
}
.dotnav li:last-child span {
  margin-right: 0;
}

CSS, ottimizzazione dello slideshow per mobile

Il nostro design è già responsivo grazie all'utilizzo di percentuali e di flexbox, ma possiamo curare i dettagli migliorando il risultato su schermi inferiori a 600px utilizzando una media query.

In particolare, su mobile possiamo nascondere il caption dell'autore e cambiare l'allineamento del caption del titolo per evitare che copra l'intera foto. Lo possiamo allineare in alto impostando justify-content: flex-start e cambiare l'animazione usando il margin-top e resettando il margin-left.

@media screen and (max-width: 599px) {
  body {
    background: black;
  }
  h1 {
    margin-bottom: 0;
  }
  .container {
    margin-top: 20px;
    padding: 10px;
  }
  .slideshow li .caption-container {
    justify-content: flex-start;
  }
  .slideshow li .caption {
    font-size: 3vw;
    width: 100%;
    margin-left: 0;
    margin-top: -100%;
    text-align: center;
  }
  .slideshow li .caption.caption-author {
    display: none;
  }
  .slideshow li.active .caption {
    margin-top: 0%;
  }
  .dotnav {
    padding: 3vw;
  }
  .dotnav li span {
    height: 3.5vw;
    width: 3.5vw;
    margin-right: 10px;
  }
}

Come farlo funzionare

Ora per farlo funzionare è sufficiente creare una funzione JavaScript che all'evento click sul pallino di navigazione assegni la classe active a se stesso e alla relativa slide. È importante rimuovere la classe active su tutti gli altri item prima di impostarla nuovamente.

Ecco un esempio di codice (JavaScript puro) per attivare la UI:

<script type="text/javascript">
function changeOrder(dot, number) {
	var slides = document.querySelectorAll(".slide");
	var dots = document.querySelectorAll(".dotnav-item");
	for (var i = 0; i < slides.length; i++) {
		slides[i].classList.remove('active');
		dots[i].classList.remove('active');
    }
	var elemName = "slide-" + number;
	var elem = document.getElementById(elemName);
	elem.classList.add('active');
	dot.classList.add('active');
}
</script>

Credit immagini Alphacoders.com

Ti consigliamo anche