Unlimited Wordpress themes, plugins, graphics & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Web Design
  2. UI Design

Costruire una linea temporale orizzontale con CSS e Javascript

by
Difficulty:IntermediateLength:LongLanguages:

Italian (Italiano) translation by Cinzia Sgariglia (you can also view the original English article)

In un articolo precedente, vi ho mostrato come costruire una linea temporale verticale adattiva da zero. Oggi, tratterò il processo di creazione della relativa linea temporale orizzontale.

Come di consueto, per avere un'idea iniziale di ciò che andremo a costruire, date un'occhiata alla demo associata su CodePen (date uno sguardo alla versione più grande per un'esperienza migliore):

Abbiamo molto da trattare, quindi iniziamo!

1. Il markup HTML 

Il markup è identico al markup che abbiamo descritto per la linea temporale verticale, eccetto che tre piccole cose:

  • Usiamo una lista ordinata invece di una lista non ordinata poiché è più corretto semanticamente.
  • C'è un elemento extra nella lista (l'ultimo) che è vuoto. In una prossima sezione, discuteremo la ragione.
  • C'è un elemento extra (cioè arrows) che è responsabile della navigazione della linea temporale.

Ecco il markup richiesto:

Lo stato iniziale della linea temporale ha questo aspetto:

2. Aggiungere gli stili CSS iniziali

Dopo alcuni stili di base per i font, gli stili per i colori, ecc. che abbiamo omesso per motivi di semplicità, specifichiamo alcune regole CSS strutturali:

La cosa più importante qui è che noterete due cose:

  • Assegniamo un padding grande alla lista in alto e in basso. Ancora, spiegheremo perché succede nella prossima sezione.
  • Come noterete nella demo seguente, a questo punto non possiamo vedere tutti gli elementi della lista perché la lista ha width: 100vw e il suo genitore ha overflow-x:hidden. Questo di fatto "maschera" gli elementi della lista. Grazie alla navigazione della linea temporale, tuttavia, saremo in grado di navigare più tardi tra gli elementi.

Con queste regole, ecco lo stato attuale della linea temporale (senza alcun contenuto reale, per mantenere le cose chiare):

3. Gli stile degli elementi della linea temporale

A questo punto daremo uno stile agli elementi div (li chiameremo "elementi della linea temporale" d'ora in poi) che sono parte degli elementi della lista così come i loro pseudo-elementi ::before.

Inoltre, useremo le pseudo-classi :nth-child(odd) e :nth-child(even) per differenziare gli stili dei div dispari e pari.

Ecco gli stili comuni per gli elementi della linea temporale:

Poi alcuni stili per quelli dispari:

E alla fine alcuni stili per quelli pari:

Ecco il nuovo stato della linea temporale con il contenuto aggiunto di nuovo:

Come avete probabilmente notato, gli elementi della linea temporale sono posizionati in modo assoluto. Ciò significa che sono rimossi dal normale flusso del documento. Con questo in mente, al fine di garantire che l'intera linea temporale appaia, dobbiamo impostare i valori del padding in alto e in basso grandi per la lista. Se non applichiamo alcun padding, la linea temporale verrà tagliata:

How the timeline looks like without paddings

4. Gli stili della navigazione della linea temporale

Ora è il momento di creare lo stile dei bottoni della navigazione. Ricordate che come impostazione predefinita disabilitiamo la freccia precedente e gli diamo la classe disabled.

Ecco gli stili CSS associati:

Le regole sopra ci danno questa linea temporale:

5. Aggiungere l'interattività

La struttura di base della linea temporale è pronta. Aggiungiamole dell'interattività!

Variabili

Prima le cose importanti, impostiamo un bel po' di variabili che useremo dopo.

Inizializzare le cose

Quando tutte le risorse della pagina sono pronte, viene chiamata la funzione init.

Questa funzione attiva quattro sotto-funzioni:

Come vedremo tra un momento, ognuna di queste funzioni compie un certo compito.

Gli elementi della linea temporale a pari altezza

Se tornate indietro all'ultima demo, noterete che gli elementi della linea temporale non hanno pari altezze. Questo non incide sulla funzionalità principale della nostra linea temporale, ma potreste preferirla se tutti gli elementi avessero la stessa altezza.  Per ottenerlo, possiamo dargli sia un'altezza fissa tramite CSS (soluzione facile) o un'altezza dinamica che corrisponde all'altezza dell'elemento più alto tramite Javascript.

La seconda opzione è più flessibile e stabile, quindi ecco una funzione che implementa questo comportamento:

Questa funzione recupera l'altezza dell'elemento più alto e lo imposta come altezza predefinita per tutti gli elementi.

Ecco come appare nella demo:

6. Animare le linea temporale

Adesso focalizziamoci sull'animazione della linea temporale. Costruiremo la funzione che implementa questo comportamento passo passo.

Primo, registriamo un listener dell'evento clic per i bottoni della linea temporale:

Ogni volta che un bottone viene cliccato, controlliamo lo stato disabilitato dei bottoni della linea temporale e se non sono disabilitati, li disabilitiamo. Ciò assicura che entrambi i bottoni saranno cliccati solo una volta fino a che l'animazione finisce.

Quindi, in termini di codice, il gestore del clic inizialmente contiene queste linee:

I prossimi passi sono i seguenti:

  • Controlliamo per vedere se è la prima volta che abbiamo cliccato su un bottone. Di nuovo, teniamo in mente che il bottone precedente sia disabilitato in modo predefinito, così il solo bottone che può essere cliccato inizialmente è quello successivo.
  • Se invece è la prima volta, usiamo la proprietà transform per muovere la linea temporale 280px a destra. Il valore della variabile xScrolling determina l'ammontare del movimento.
  • Al contrario, se abbiamo già cliccato su un bottone, ritroviamo il valore attuale di transform della linea temporale e aggiungiamo o rimuoviamo a quel valore l'ammontare desiderato del movimento (cioè 280px). Quindi, fintanto che clicchiamo sul bottone precedente, il valore della proprietà transform diminuisce e la linea temporale viene spostata da sinistra a destra. Tuttavia, quando il bottone successivo viene cliccato, il valore della proprietà transform aumenta e la linea temporale viene spostata da destra a sinistra.

Il codice che implementa questa funzionalità è il seguente:

Bel lavoro! Abbiamo appena definito un modo per animare la linea temporale. La prossima sfida è di capire quando questa animazione dovrebbe fermarsi. Ecco il nostro approccio:

  • Quando il primo elemento della linea temporale diventa totalmente visibile, significa che abbiamo già raggiunto l'inizio della linea temporale e perciò disabilitiamo il bottone precedente. Ci assicuriamo anche che il bottone successivo sia abilitato.
  • Quando l'ultimo elemento diventa totalmente visibile, significa che abbiamo già raggiunto la fine della linea temporale e perciò disabilitiamo il bottone successivo. Pertanto, ci assicuriamo anche il bottone precedente sia abilitato.

Ricordate che l'ultimo elemento è vuoto con larghezza uguale alla larghezza degli elementi della linea temporale (cioè 280px). Gli diamo questo valore (o un valore più alto) perché vogliamo essere sicuri che l'ultimo elemento della linea temporale sarà visibile prima di disabilitare il bottone successivo.

Per rilevare se determinati elementi sono o meno totalmente visibili nell'area visibile attuale, approfitteremo dello stesso codice che abbiamo usato per la linea temporale verticale. Il codice richiesto che proviene da questa conversazione su Stack Overflow è il seguente:

Oltre alla funzione sopra, definiamo un altro helper:

Questa funzione aggiunge o rimuove la classe disabled da un elemento basata sul valore del parametro flag. In più, può cambiare lo stato di disabilitato da questo elemento.

Dato quello che abbiamo descritto sopra, ecco il codice che definiamo per controllare se l'animazione dovrebbe fermarsi o no:

Notate che c'è 1.1 secondo di ritardo prima di eseguire questo codice. Perché accade questo?

Se torniamo al nostro CSS, vedremo questa regola:

Quindi, l'animazione della linea temporale ha bisogno di 1 secondo per completarsi. Finché si completa, aspettiamo 100 millisecondi e poi effettuiamo i nostri controlli.

Ecco la linea temporale con le animazioni:

7. Aggiungere il supporto per swipe

Finora, la linea temporale non risponde agli eventi touch. Però sarebbe bello se potessimo aggiungere questa funzionalità. Per realizzarla, possiamo scrivere la nostra implementazione Javascript o usare una delle librerie collegate (per es. Hammer.js, TouchSwipe.js) che esistono in rete.

Per la nostra dimostrazione, semplificheremo e useremo Hammer.js, quindi per prima cosa, inseriamo questa libreria nel nostro CodePen:

How to include Hammerjs in our pen

Poi dichiariamo la funzione associata:

All'interno della funzione sopra, procediamo come segue:

  • Create un'istanza di Hammer.
  • Registrate gli handler per gli eventi swipeleft e swiperight
  • Quando strisciamo sulla linea temporale nella direzione sinistra, provochiamo un clic sul bottone successivo e quindi la linea temporale è animata da destra a sinistra.
  • Quando strisciamo sulla linea temporale nella direzione destra, provochiamo un clic sul bottone precedente e quindi la linea temporale è animata da sinistra a destra.

La linea temporale con il supporto per swipe:

Aggiungere la navigazione da tastiera

Aumentiamo ulteriormente l'esperienza utente fornendo il supporto per la navigazione dalla tastiera. I nostri obiettivi:

  • Quando vengono premuti il tasto freccia sinistra o destra, il documento dovrebbe scorrere dalla posizione in alto della linea temporale (se un'altra sezione della pagina è attualmente visibile). Ciò assicura che l'intera linea temporale sarà visibile.
  • Nello specifico, quando viene premuto il tasto freccia sinistra, la linea temporale dovrebbe essere animata da sinistra verso destra.
  • Allo stesso modo, quando viene premuto il tasto freccia destra, la linea temporale dovrebbe essere animata da destra verso sinistra.

La funzione associata è la seguente:

La linea temporale con il supporto per la tastiera:

8. Rendere responsive

Abbiamo quasi fatto! Ultimo ma non meno importante, rendiamo la linea temporale responsive. Quando il viewport è meno di 600px, dovrebbe avere il seguente disposizione del layout:

Poiché stiamo usando l'approccio prima il desktop, ecco le regole CSS che dobbiamo sovrascrivere:

Nota: Per due delle regole sopra, abbiamo dovuto usare la regola !important per superare gli stili inline collegati applicati tramite Javascript.

Lo stato finale della linea temporale:

Il supporto browser

la dimostrazione funziona bene in tutti i browser e dispositivi recenti. Inoltre, come forse avete notato, usiamo Babel per compilare il nostro codice ES6 fino a ES5.

L'unico piccolo problema che ho incontrato durante la verifica è il cambiamento di rendering del testo quando la linea temporale viene animata. Sebbene abbia provato vari approcci proposti su diverse conversazioni su Stack Overflow, non ho trovato una soluzione chiara per tutti i sistemi operativi e i browser. Quindi, ricordate che potreste vedere piccoli problemi di rendering dei caratteri non appena la linea temporale viene animata.

Conclusioni

In questo tutorial abbastanza sostanzioso, abbiamo iniziato con una semplice lista ordinata e abbiamo creato una linea temporale orizzontale responsive. Senza dubbio, abbiamo coperto molte cose interessanti, ma spero che vi siate divertiti a lavorare verso il risultato finale e che vi abbia aiutato a guadagnare delle nuove conoscenze.

Se avete delle domande o se c'è qualcosa che non avete capito, fatemelo sapere nei commenti qui sotto!

Prossimi passi

Se volete migliorare ulteriormente o estendere questa linea temporale, ecco alcune cose che potete fare:

  • Aggiungere il supporto per il trascinamento. Invece di cliccare i bottoni della linea temporale per navigare, potreste solo trascinare l'area della linea temporale. Per questo comportamento, potreste usare sia l'API Drag and Drop nativa (la quale per sfortuna non supporta i dispositivi mobili in questo momento) oppure una libreria esterna come Draggable.js.
  • Migliorare il comportamento della linea temporale non appena ridimensioniamo la finestra del browser. Per esempio, non appena ridimensioniamo la finestra, i bottoni dovrebbero essere abilitati e disabilitati di conseguenza.
  • Organizzare il codice in un modo più gestibile. Forse, usare un normale Javascript Design Pattern.
Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.