Creare un componente Storie

Una panoramica di base su come creare un'esperienza simile a quella delle Storie di Instagram sul web.

In questo post voglio condividere alcune idee sulla creazione di un componente di Storie per il web che sia responsive, supporti la navigazione con la tastiera e funzioni su tutti i browser.

Demo

Se preferisci una dimostrazione pratica su come creare personalmente questo componente Storie, consulta il codelab del componente Storie.

Se preferisci i video, ecco una versione di questo post su YouTube:

Panoramica

Due esempi popolari di UX delle Storie sono le Storie di Snapchat e le Storie di Instagram (per non parlare dei parchi risorse). In termini generali di UX, le Storie sono in genere un pattern incentrato sui tocchi e solo per dispositivi mobili per navigare tra più abbonamenti. Ad esempio, su Instagram, gli utenti aprono la storia di un amico e guardano le immagini al suo interno. In genere fanno molte amicizie contemporaneamente. Se tocca il lato destro del dispositivo, l'utente passa alla storia successiva dell'amico. Se scorre verso destra, l'utente passa a un altro amico. Un componente Storia è abbastanza simile a un carosello, ma consente di navigare in un array multidimensionale anziché in un array monodimensionale. È come se ci fosse un carosello all'interno di ogni carosello. 🤯

Array multidimensionale visualizzato utilizzando le schede. Da sinistra a destra c'è una pila di carte con bordi viola e all'interno di ogni carta ci sono 1-molte carte con bordo ciano. Elenco in un elenco.
1° carosello di amici
2° carosello "impiegato" di storie
👍 Elenco in un elenco, ovvero un array multidimensionale

Scegliere gli strumenti giusti per il lavoro

Nel complesso, ho trovato questo componente piuttosto semplice da creare, grazie ad alcune funzionalità fondamentali della piattaforma web. Vediamole insieme!

Griglia CSS

Il nostro layout non ha rappresentato un problema per CSS Grid, in quanto è dotato di alcuni metodi efficaci per gestire i contenuti.

Layout di Amici

Il nostro wrapper del componente principale .stories è una visualizzazione di scorrimento orizzontale orientata ai dispositivi mobili:

.stories {
  inline-size: 100vw;
  block-size: 100vh;

  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;

  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}

/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
  max-inline-size: 480px;
  max-block-size: 848px;
}
Utilizzo della modalità Dispositivo di Chrome DevTools per evidenziare le colonne create da Grid

Analizziamo il layout grid:

  • Riempiamo esplicitamente l'area visibile sui dispositivi mobili con 100vh e 100vw e limitiamo le dimensioni sui computer desktop
  • / separa i modelli di righe e colonne
  • auto-flow si traduce in grid-auto-flow: column
  • Il modello di flusso automatico è 100%, che in questo caso corrisponde alla larghezza della finestra di scorrimento

Su un cellulare, immagina che le dimensioni della riga corrispondano all'altezza dell'area visibile e ogni colonna alla larghezza dell'area visibile. Se continuiamo con l'esempio di Storie di Snapchat e Storie di Instagram, ogni colonna sarà la storia di un amico. Vogliamo che le storie degli amici continuino fuori dall'area visibile, in modo da avere un punto da scorrere. La griglia creerà tutte le colonne necessarie per il layout del codice HTML di ogni storia di un amico, creando un contenitore scorrevole dinamico e adattabile. La griglia ci ha permesso di centralizzare l'intero effetto.

Impilaggio

Per ogni amico, abbiamo bisogno delle loro storie in uno stato pronto per l'impaginazione. In preparazione all'animazione e ad altri pattern divertenti, ho scelto una serie. Quando dico "impilare", intendo come se guardassi dall'alto un panino, non come se lo guardassi di lato.

Con la griglia CSS, possiamo definire una griglia a una cella (ovvero un quadrato), in cui le righe e le colonne condividono un alias ([story]), quindi ogni elemento secondario viene assegnato a questo spazio a una cella con alias:

.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
.story {
  grid-area: story;
  background-size: cover;
  
}

In questo modo, il nostro codice HTML controlla l'ordine di impilamento e mantiene tutti gli elementi in flusso. Come puoi notare, non abbiamo dovuto modificare il posizionamento di absolute o z-index e non abbiamo dovuto inserire correttamente height: 100% o width: 100%. La griglia principale definiva già le dimensioni dell'area visibile dell'immagine della storia, quindi non era necessario indicare nessuno di questi componenti della storia per riempirlo.

Punti di aggancio di scorrimento CSS

La specifica dei punti di aggancio di scorrimento CSS consente di bloccare gli elementi nell'area visibile quando si scorre. Prima che queste proprietà CSS esistessero, dovevi utilizzare JavaScript ed era... a dir poco complicato. Consulta Introduzione ai punti di aggancio dello scorrimento CSS di Sarah Drasner per una panoramica dettagliata su come utilizzarli.

Scorrimento orizzontale senza e con stili scroll-snap-points. In caso contrario, gli utenti possono scorrere liberamente come di consueto. In questo modo, il browser si appoggia delicatamente su ogni articolo.
principale
.stories {
  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}
Il publisher principale con overscroll definisce il comportamento di agganciamento.
bambino
.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
I bambini attivano la funzionalità che li rende target di uno scatto.

Ho scelto i punti di aggancio scorrevoli per diversi motivi:

  • Accessibilità senza costi. La specifica dei punti di agganciamento di scorrimento indica che, per impostazione predefinita, i tasti Freccia sinistra e Freccia destra devono spostarsi tra i punti di agganciamento.
  • Una specifica in continua evoluzione. La specifica dei punti di aggancio allo scorrimento viene costantemente migliorata e integrata con nuove funzionalità, il che significa che il mio componente di Storie migliorerà sempre di più.
  • Facilità di implementazione. I punti di aggancio di scorrimento sono realizzati praticamente per il caso d'uso di paginazione orizzontale centrica al tocco.
  • Inerzia libera in stile piattaforma. Ogni piattaforma scorrerà e si fermerà nel proprio stile, a differenza dell'inerzia normalizzata che può avere uno stile di scorrimento e riposo innaturale.

Compatibilità tra browser

Abbiamo eseguito test su Opera, Firefox, Safari e Chrome, oltre che su Android e iOS. Ecco un breve riepilogo delle funzionalità web in cui abbiamo riscontrato differenze in termini di funzionalità e assistenza.

Tuttavia, alcuni CSS non sono stati applicati, quindi alcune piattaforme al momento non dispongono delle ottimizzazioni UX. Mi è piaciuto non dover gestire queste funzionalità e sono certo che alla fine raggiungeranno altri browser e piattaforme.

scroll-snap-stop

I caroselli erano uno dei principali casi d'uso UX che hanno dato origine alla creazione della specifica CSS Scroll Snap Points. A differenza delle Storie, un carosello non deve sempre fermarsi su ogni immagine dopo che un utente interagisce con essa. Potrebbe essere consentito o incoraggiato scorrere rapidamente il carosello. Le Storie, invece, sono più adatte per essere visualizzate una alla volta, e questo è esattamente ciò che offre scroll-snap-stop.

.user {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

Al momento della stesura di questo post, scroll-snap-stop è supportato solo sui browser basati su Chromium. Consulta gli aggiornamenti Compatibilità del browser. Tuttavia, non è un blocco. Significa solo che su browser non supportati gli utenti possono saltare accidentalmente un amico. Gli utenti dovranno quindi fare più attenzione oppure dovremo scrivere codice JavaScript per assicurarci che un amico saltato non venga contrassegnato come visualizzato.

Se ti interessa, scopri di più nella specifica.

overscroll-behavior

Ti è mai capitato di scorrere un modale quando improvvisamente hai iniziato a scorrere i contenuti dietro la finestra modale? overscroll-behavior consente allo sviluppatore di bloccare lo scorrimento e di non farlo mai uscire. È un'idea carina per ogni tipo di occasione. Il componente Le mie Storie lo utilizza per impedire che ulteriori gesti di scorrimento e scorrimento interrompano il componente.

.stories {
  overflow-x: auto;
  overscroll-behavior: contain;
}

Safari e Opera sono i 2 browser che non supportavano questa funzionalità, e va benissimo. Questi utenti usufruiranno di un'esperienza di scorrimento orizzontale come sempre e potrebbero non notare mai questo miglioramento. Personalmente lo adoro e mi piace includerlo in quasi tutte le funzionalità di scorrimento verticale che implemento. È un'aggiunta innocua che può solo migliorare la UX.

scrollIntoView({behavior: 'smooth'})

Quando un utente tocca o fa clic e ha raggiunto la fine della serie di Storie di un amico, è il momento di passare all'amico successivo nel punto di aggancio dello scorrimento impostato. Con JavaScript, siamo riusciti a fare riferimento al prossimo amico e a richiedere che se potesse essere visualizzato tramite scorrimento. Il supporto per le nozioni di base è eccellente: ogni browser lo ha fatto scorrere per visualizzarlo. Tuttavia, non tutti i browser lo hanno fatto 'smooth'. Ciò significa semplicemente che è stato visualizzato tramite scorrimento anziché essere agganciato.

element.scrollIntoView({
  behavior: 'smooth'
})

Safari era l'unico browser a non supportare behavior: 'smooth' qui. Consulta gli aggiornamenti Compatibilità del browser.

Pratico

Ora che sai come ci ho fatto, come lo faresti?! Diversifichiamo i nostri approcci e scopriamo tutti i modi per creare sul web. Crea un glitch, twittami la tua versione e la aggiungerò alla sezione Remix della community di seguito.

Remix della community