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 della creazione di questo componente di Storie, consulta il codelab del componente di 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 solo per dispositivi mobili per navigare tra più iscrizioni. Ad esempio, su Instagram, gli utenti aprono la storia di un amico e guardano le immagini al suo interno. In genere lo fanno con molti amici 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 Story è abbastanza simile a un carosello, ma consente di navigare in un array multi-dimensionale 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 è presente una serie di schede con bordi viola e all'interno di ogni scheda sono presenti 1-molte schede con bordi azzurri. 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 abbastanza semplice da creare, grazie a alcune funzionalità critiche della piattaforma web. Copriamoli.

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 componente wrapper .stories principale è una scrollview orizzontale mobile-first:

.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:

  • Riempriamo esplicitamente l'area visibile sui dispositivi mobili con 100vh e 100vw e limitiamo le dimensioni sui computer
  • / 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 delle Storie di Snapchat e di Instagram, ogni colonna sarà la storia di un amico. Vogliamo che le Storie degli amici continuino all'esterno dell'area visibile, in modo da avere un punto di scorrimento. 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. Grid ci ha permesso di centralizzare l'intero effetto.

Impilaggio

Per ogni amico, abbiamo bisogno che le sue Storie siano pronte per la paginazione. 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 codice HTML controlla l'ordine di impilamento e mantiene tutti gli elementi in sequenza. Tieni presente che non è stato necessario fare nulla per il posizionamento absolute o z-index e non è stato necessario correggere la casella con height: 100% o width: 100%. La griglia principale ha già definito le dimensioni dell'area visibile dell'immagine della storia, quindi non è stato necessario chiedere a nessuno di questi componenti della storia di riempirla.

Punti di aggancio scorrimento CSS

La specifica dei punti di aggancio allo scorrimento CSS semplifica notevolmente il blocco degli elementi nell'area visibile durante lo scorrimento. Prima dell'esistenza di queste proprietà CSS, dovevate utilizzare JavaScript ed era… complicato, per non dire altro. 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;
}
L'elemento principale con overscroll definisce il comportamento di agganci.
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 aggancio dello scorrimento indica che la pressione dei tasti Freccia sinistra e Freccia destra dovrebbe consentire di spostarsi tra i punti di aggancio per impostazione predefinita.
  • 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 dello scorrimento sono progettati per il caso d'uso della paginazione orizzontale incentrata sul 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à cross-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. Per aggiornamenti, consulta la sezione 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 una finestra modale quando all'improvviso inizi a scorrere i contenuti dietro la finestra? 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 erano i due browser che non lo supportavano, ma non c'è alcun problema. Questi utenti avranno un'esperienza di scorrimento oltre i limiti abituale e potrebbero non notare mai questo miglioramento. Personalmente lo adoro e mi piace includerlo in quasi tutte le funzionalità di scorrimento verticale che implemento. Si tratta di un'aggiunta innocua che può solo migliorare l'esperienza utente.

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 all'amico successivo e a richiederne la visualizzazione tramite scorrimento. Il supporto per le nozioni di base è ottimo; ogni browser lo ha visualizzato scorrendo. 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. Per aggiornamenti, consulta la sezione Compatibilità del browser.

Hands-on

Ora che sai come ho fatto, come 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