Scorrimento ben controllato con CSS Scroll Snap

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

La funzionalità CSS Scroll Snap consente agli sviluppatori web di creare esperienze di scorrimento ben controllate dichiarando le posizioni di allineamento dello scorrimento. Gli articoli impaginati e i caroselli di immagini sono due esempi di utilizzo comune. CSS Scroll Snap fornisce un'API facile da usare e coerente per creare questi pattern UX molto diffusi.

Sfondo

Il caso dell'allineamento dello scorrimento

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

Lo svantaggio principale dello scorrimento è la mancanza di precisione. Raramente uno scorrimento termina allineato a un paragrafo o a una frase. Questo è ancora più evidente per i contenuti impaginati o suddivisi in elementi con confini significativi quando lo scorrimento termina al centro della pagina o dell'immagine, lasciandola parzialmente visibile. Questi casi d'uso traggono vantaggio da un'esperienza di scorrimento ben controllata.

Gli sviluppatori web si affidano da tempo a soluzioni basate su JavaScript per controllare lo scorrimento e contribuire a risolvere questo problema. Tuttavia, le soluzioni basate su JavaScript non forniscono una soluzione di fedeltà completa a causa della mancanza di primitive di personalizzazione dello scorrimento o dell'accesso allo scorrimento composito. CSS Scroll Snap garantisce una soluzione rapida, ad alta fedeltà e facile da usare che funziona in modo coerente su tutti i browser.

L'allineamento dello scorrimento CSS consente agli autori web di contrassegnare ogni contenitore di scorrimento con i limiti per le operazioni di scorrimento da completare. I browser scelgono quindi la posizione finale più appropriata in base alle caratteristiche dell'operazione di scorrimento, al layout e alla visibilità del container di scorrimento e ai dettagli delle posizioni di aggancio, quindi eseguono un'animazione fluida. Tornando all'esempio precedente, quando l'utente termina lo scorrimento del carosello, l'immagine visibile si blocca in posizione. Non sono necessarie regolazioni dello scorrimento da parte di JavaScript.

Esempio di utilizzo dell'allineamento dello scorrimento CSS con un carosello di immagini.
Esempio di utilizzo dell'allineamento dello scorrimento CSS con un carosello di immagini. In questo caso, l'allineamento dello scorrimento garantisce che, al termine dello scorrimento, il centro orizzontale di un'immagine sia allineato al centro orizzontale del container di scorrimento.

Allineamento dello scorrimento CSS

L'allineamento dello scorrimento consiste nel regolare l'offset di scorrimento di un contenitore di scorrimento in modo che si trovi in una posizione di allineamento preferita al termine dell'operazione di scorrimento.

Un container di scorrimento può essere attivato per l'allineamento dello scorrimento utilizzando la proprietà scroll-snap-type. In questo modo, il browser sa che deve prendere in considerazione l'allineamento di questo contenitore di scorrimento alle posizioni di allineamento prodotte dai suoi discendenti. scroll-snap-type determina l'asse su cui avviene lo scorrimento: x, y o both e la rigidità dello snap: mandatory, proximity. Ne parleremo più avanti.

Una posizione di aggancio può essere prodotta dichiarando un allineamento desiderato su un elemento. Questa posizione è l'offset di scorrimento in cui il container di scorrimento 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 iniziale dello snapport del container di scorrimento deve essere allineato al bordo iniziale dell'area di aggancio dell'elemento. Analogamente, gli allineamenti end e center indicano che il bordo finale o il centro dello snapport del container di scorrimento deve essere allineato al bordo finale o al centro dell'area di aggancio dell'elemento.

Esempio di vari allineamenti sull'asse di scorrimento orizzontale.

I seguenti esempi illustrano come utilizzare questi concetti.

Un caso d'uso comune per l'allineamento dello scorrimento è 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 container 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 aggancio sono associate a un elemento, l'algoritmo di aggancio può essere intelligente su quando e come agganciare l'elemento e le dimensioni del contenitore di scorrimento. Ad esempio, considera il caso in cui un'immagine è più grande del carosello. Un algoritmo di aggancio ingenuo potrebbe impedire all'utente di spostarsi per visualizzare l'immagine completa. Tuttavia, la specifica richiede che le implementazioni rilevino questo caso e consentano all'utente di scorrere liberamente all'interno dell'immagine, agganciandosi solo ai bordi.

Esempio: una pagina di prodotto con un percorso

Un altro caso comune che può trarre vantaggio dall'allineamento dello scorrimento sono le pagine con più sezioni logiche da scorrere verticalmente, ad esempio una tipica pagina di prodotto. scroll-snap-type: y proximity; è più adatto 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 scorre abbastanza vicino.

Ecco come fare:

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 di prodotto ha un'intestazione superiore con posizione fissa. Il design richiedeva anche che una parte della sezione superiore rimanesse visibile quando il contenitore di scorrimento viene agganciato, in modo da fornire agli utenti un indizio visivo sui contenuti sopra.

La proprietà scroll-padding è una nuova proprietà CSS che può essere utilizzata per regolare l'area visibile effettiva del container di scorrimento o snapport, che viene utilizzata per calcolare gli allineamenti dello scorrimento. La proprietà definisce un inset rispetto alla casella di spaziatura interna del container di scorrimento. Nel nostro esempio, è stato aggiunto un inset aggiuntivo di 15vh nella parte superiore, che indica al browser di considerare una posizione più bassa, 15vh sotto il bordo superiore del container di scorrimento, come bordo iniziale verticale per l'allineamento dello scorrimento. Durante l'aggancio, il bordo iniziale dell'elemento target di aggancio verrà allineato a questa nuova posizione, lasciando spazio sopra.

La proprietà scroll-margin definisce la quantità di outset utilizzata per regolare la casella effettiva del target di aggancio, in modo simile al funzionamento di scroll-padding sul container di scorrimento con 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 solo per l'allineamento dello scorrimento. Ad esempio, Chrome ne tiene conto quando calcola le dimensioni della pagina per le operazioni di scorrimento della pagina, come PageDown e PageUp, e anche quando calcola la quantità di scorrimento per l'operazione Element.scrollIntoView().

Interazione con altre API di scorrimento

API DOM Scrolling

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

Scorrimento fluido

Lo scorrimento fluido controlla il comportamento di un'operazione di scorrimento programmatica, mentre l'allineamento dello scorrimento ne determina la destinazione. Poiché controllano aspetti ortogonali dello scorrimento, possono essere utilizzati insieme e si completano a vicenda.

Comportamento di overscroll

L'API Overscroll Behavior controlla il modo in cui lo scorrimento viene concatenato tra più elementi e non è interessata dall'allineamento dello scorrimento.

Avvertenze e best practice

Evita di utilizzare lo snapping obbligatorio quando gli elementi target sono molto distanziati tra loro. Ciò può rendere inaccessibili i contenuti tra le posizioni di aggancio.

In molti casi, l'allineamento dello scorrimento può essere aggiunto come miglioramento senza dover eseguire il rilevamento delle funzionalità. Se necessario, utilizza @supports o CSS.supports per rilevare il supporto per l'allineamento dello scorrimento CSS. Evita di utilizzare scroll-snap-type, che è presente anche nella specifica deprecata.

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. L'allineamento dello scorrimento potrebbe regolare l'offset di scorrimento al termine dello scorrimento programmatico. Tieni presente che questa non era una buona ipotesi anche prima dell'allineamento dello scorrimento, poiché lo scorrimento potrebbe essere stato interrotto per altri motivi, ma è particolarmente vero con l'allineamento dello 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 di plug-in e i CSS. Il lavoro futuro si concentrerà su scroll-snap, tra cui:

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