Scorrimento ben controllato con CSS Scroll Snap

Crea esperienze di scorrimento ben controllate dichiarando le posizioni di aggancio dello scorrimento.

Robert Flack
Robert Flack
Majid Valipour
Majid Valipour

La funzionalità Scroll Snap CSS consente agli sviluppatori web di creare esperienze di scorrimento ben controllate dichiarando le posizioni di snap dello scorrimento. Gli articoli paginati e i caroselli di immagini sono due esempi di questo tipo di contenuti molto utilizzati. CSS Scroll Snap fornisce un'API coerente e facile da usare per la creazione di questi pattern di UX molto diffusi.

Sfondo

Il caso dell'aggancio allo scorrimento

Lo scorrimento è un modo popolare e naturale per interagire con i contenuti sul web. È il mezzo nativo della piattaforma per fornire accesso a più informazioni di quante siano visibili contemporaneamente sullo schermo, diventando particolarmente importante sulle piattaforme mobile con uno spazio sullo schermo limitato. Non sorprende quindi che gli autori web scelgano sempre più spesso di organizzare i contenuti in elenchi piatti scorrevoli anziché in gerarchie complesse.

Lo svantaggio principale dello scorrimento è la mancanza di precisione. Raramente una scorrimento termina allineata a un paragrafo o a una frase. Questo è ancora più evidente per i contenuti paginati o elencati con confini significativi quando lo scorrimento termina al centro della pagina o dell'immagine, lasciandola parzialmente visibile. Questi casi d'uso beneficiano di un'esperienza di scorrimento ben controllata.

Per molto tempo gli sviluppatori web si sono affidati a soluzioni basate su JavaScript per controllare scorrimento per risolvere questo problema. Tuttavia, le soluzioni basate su JavaScript non riescono a fornire una soluzione con una fedeltà completa a causa della mancanza di primitive di personalizzazione dello scorrimento o dell'accesso allo scorrimento composito. La funzionalità CSS Scroll Snap garantisce una soluzione rapida, ad alta fedeltà e facile da usare che funziona in modo coerente su tutti i browser.

La funzionalità di snap della barra di scorrimento CSS consente agli autori web di contrassegnare ogni contenitore della barra di scorrimento con i limiti per le operazioni di scorrimento da completare. I browser scelgono quindi la posizione finale più appropriata in base ai dettagli dell'operazione di scorrimento, al layout e alla visibilità del contenitore di scorrimento e ai dettagli delle posizioni di agganci, quindi la animano in modo fluido. Tornando all'esempio precedente, quando l'utente termina di scorrere il carosello, l'immagine visibile si inserisce in posizione. Non sono necessarie modifiche allo scorrimento da parte di JavaScript.

Esempio di utilizzo di css scroll snap con un carosello di immagini.
Esempio di utilizzo di css scroll snap con un carosello di immagini. Qui, l'aggancio allo scorrimento garantisce che alla fine dello scorrimento il centro orizzontale di un'immagine sia allineato al centro orizzontale del contenitore di scorrimento.

Snap scorrimento CSS

Lo snap di scorrimento consiste nell'aggiustare l'offset di scorrimento di un contenitore di scorrimento in modo che al termine dell'operazione di scorrimento si trovi in una posizione di snap preferita.

È possibile attivare l'aggancio allo scorrimento di un contenitore di scorrimento utilizzando la proprietà scroll-snap-type. Questo indica al browser che deve considerare l'aggancio di questo container scorrevole alle posizioni di aggancio prodotte dai suoi discendenti. scroll-snap-type determina l'asse su cui avviene lo scorrimento: x, y o both, nonché la severità dell'aggancio: mandatory, proximity. Ne parleremo più avanti.

Una posizione di agganciamento può essere prodotta dichiarando un allineamento desiderato su un elemento. Questa posizione è l'offset di scorrimento in cui il contenitore scorrevole dell'antenato più vicino e l'elemento sono allineati come specificato per l'asse specificato. Su ogni asse sono possibili i seguenti allineamenti: start, end, center.

Un allineamento start indica che il bordo di inizio della porta di aggancio del contenitore scorrevole deve essere allineato al bordo di inizio dell'area di aggancio dell'elemento. Analogamente, gli allineamenti end e center indicano che il bordo o il centro finale della porta di aggancio del contenitore scorrevole deve essere allineato al bordo o al centro finale dell'area di aggancio dell'elemento.

Esempio di vari allineamenti sull'asse di scorrimento orizzontale.

Gli esempi riportati di seguito illustrano come utilizzare questi concetti.

Un caso d'uso comune per lo snap scorrevole è un carosello di immagini. Ad esempio, per creare un carosello di immagini orizzontale che si aggancia a ogni immagine durante lo scorrimento, possiamo specificare che il contenitore di scorrimento abbia un scroll-snap-type obbligatorio sull'asse orizzontale. Imposta ogni immagine su scroll-snap-align: center per assicurarti che l'aggancio centri l'immagine all'interno del carosello.

#gallery {
  scroll-snap-type: x mandatory;
  overflow-x: scroll;
  display: flex;
}

#gallery img {
   scroll-snap-align: center;
}
<div id="gallery">
  <img src="cat.jpg">
  <img src="dog.jpg">
  <img src="another_cute_animal.jpg">
</div>

Poiché le posizioni di agganci sono associate a un elemento, l'algoritmo di agganci può essere intelligente su quando e come applicare l'aggancio in base all'elemento e alle dimensioni del contenitore scorrevole. Ad esempio, prendi in considerazione il caso in cui un'immagine sia più grande del carousel. Un algoritmo di agganci semplici potrebbe impedire all'utente di eseguire la panoramica per vedere l'immagine completa. Tuttavia, la specifica richiede alle implementazioni di rilevare questo caso e consentire all'utente di scorrere liberamente all'interno dell'immagine solo scattando ai bordi.

Visualizza la demo | Codice sorgente

Esempio: una pagina di prodotto con percorso

Un altro caso comune che può trarre vantaggio dall'aggancio allo scorrimento sono le pagine con più sezioni logiche da scorrere verticalmente, ad esempio una tipica pagina di prodotto. scroll-snap-type: y proximity; è una soluzione più adatta per casi come questo. Non interferisce quando un utente scorre fino al centro di una determinata sezione, ma si aggancia e attira l'attenzione su una nuova sezione quando l'utente scorri abbastanza vicino.

Ecco come:

article {
  scroll-snap-type: y proximity;
  /* Reserve space for header plus some extra space for sneak peeking. */
  scroll-padding-top: 15vh;
  overflow-y: scroll;
}
section {
  /* Snap align start. */
  scroll-snap-align: start;
}
header {
  position: fixed;
  height: 10vh;
}
<article>
  <header> Header </header>
  <section> Section One </section>
  <section> Section Two </section>
  <section> Section Three </section>
</article>

Spaziatura interna e margine di scorrimento

La pagina del prodotto ha un'intestazione superiore in posizione fissa. Il design prevedeva inoltre che parte della sezione superiore rimanesse visibile quando il contenitore di scorrimento viene agganciato per fornire agli utenti un indizio di design sui contenuti soprastanti.

La proprietà scroll-padding è una nuova proprietà CSS che può essere utilizzata per regolare la regione visibile effettiva del contenitore di scorrimento o snapport, che viene utilizzata per calcolare gli allineamenti di snap dello scorrimento. La proprietà definisce un inset nei confronti della casella di spaziatura del contenitore di scorrimento. Nel nostro esempio, è stato aggiunto un 15vh incavo aggiuntivo nella parte superiore, che indica al browser di prendere in considerazione una posizione inferiore, 15vh sotto il bordo superiore del contenitore di scorrimento, come bordo di inizio verticale per lo snap dello scorrimento. Durante l'aggancio, il bordo iniziale dell'elemento di destinazione dell'aggancio verrà allineato a questa nuova posizione, lasciando spazio sopra.

La proprietà scroll-margin definisce l'importo dell'esclusione utilizzato per regolare la casella effettiva del target di aggancio in modo simile al funzionamento di scroll-padding nel contenitore di scorrimento di aggancio.

Potresti aver notato che queste due proprietà non contengono la parola "snap". Questo è intenzionale in quanto modificano effettivamente la casella per tutte le operazioni di scorrimento pertinenti e non sono solo scatti di scorrimento. Ad esempio, Chrome li prende in considerazione quando calcola le dimensioni di pagina per le operazioni di scorrimento delle pagine, come PageDown e PageUp, nonché per il calcolo dell'importo dello scorrimento per l'operazione Element.scrollIntoView().

Visualizza la demo | Codice sorgente

Interazione con altre API di scorrimento

API DOM Scrolling

L'aggancio allo scorrimento avviene dopo tutte le operazioni di scorrimento, incluse quelle avviate tramite script. Quando utilizzi API come Element.scrollTo, il browser calcola la posizione di scorrimento prevista dell'operazione, quindi applica la logica di agganci appropriata per trovare la posizione finale agganciata. Pertanto, non è necessario che lo script utente esegua calcoli manuali per l'aggancio.

Scorrimento fluido

Lo scorrimento fluido controlla il comportamento di un'operazione di scorrimento programmatico, mentre lo snap scorrimento ne determina la destinazione. Poiché controllano aspetti ortogonali dello scorrimento, possono essere utilizzati insieme e completarsi a vicenda.

Comportamento di overscroll

L'API di comportamento di scorrimento eccessivo controlla in che modo scorrimento viene collegato a più elementi e non è interessato dallo snap scorrimento.

Limitazioni e best practice

Evita di utilizzare l'aggancio obbligatorio quando gli elementi target sono molto distanziati. Ciò può causare l'inaccessibilità dei contenuti tra le posizioni di snap.

In molti casi, la funzionalità di scorrimento automatico può essere aggiunta come miglioramento senza dover eseguire il rilevamento delle funzionalità. Se necessario, utilizza @supports o CSS.supports per rilevare il supporto di CSS Scroll Snap. Evita di utilizzare scroll-snap-type, che è presente anche nella specifica ritirata.

Rilevamento delle funzionalità in CSS

@supports (scroll-snap-align: start) {
  article {
    scroll-snap-type: y proximity;
    scroll-padding-top: 15vh;
    overflow-y: scroll;
  }
}

Rilevamento delle funzionalità in JavaScript

if (CSS.supports('scroll-snap-align: start')) {
  // use css scroll snap
} else {
  // use fallback
}

Non dare per scontato che le API di scorrimento programmatico come Element.scrollTo terminino sempre con l'offset di scorrimento richiesto. La funzionalità di aggancio allo scorrimento potrebbe regolare l'offset scorrimento al termine dello scorrimento programmatico. Tieni presente che non si trattava di un presupposto valido anche prima dell'aggiornamento di scorrimento, poiché lo scorrimento potrebbe essere stato interrotto per altri motivi, ma è particolarmente il caso dell'aggiornamento di scorrimento.

Lavoro futuro

L'esperienza di scorrimento è stata al centro di un recente sondaggio del team di Chrome. I risultati del sondaggio hanno identificato diverse aree che richiedono ulteriore lavoro per ridurre il divario tra le librerie dei plug-in e il CSS. I lavori futuri si concentreranno su scroll-snap, tra cui:

  1. Disponibilità e compatibilità dell'API nei vari browser.
  2. Lavora su nuove API CSS come scroll-start.
  3. Lavora su nuovi eventi JS come snapChanged().