Scorrimento ben controllato con CSS Scroll Snap

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

Robert Flack
Robert Flack
Majid Valipour
Majid Valipour

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

Sfondo

Il caso dello scorrimento agganciato

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 sullo schermo contemporaneamente, diventando particolarmente importante 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 sua mancanza di precisione. Raramente uno scorrimento si allinea a un paragrafo o a una frase. Questo è ancora più evidente per i contenuti paginati o suddivisi in elementi con limiti significativi quando lo scorrimento termina a metà 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 questa carenza. Tuttavia, le soluzioni basate su JavaScript non riescono a fornire una soluzione a fedeltà completa a causa della mancanza di primitive di personalizzazione dello scorrimento o dell'accesso allo scorrimento composito. CSS Scroll Snap garantisce una soluzione veloce, ad alta fedeltà e facile da usare che funziona in modo coerente su tutti i browser.

CSS Scroll Snap consente agli autori web di contrassegnare ogni contenitore di scorrimento con i limiti per le operazioni di scorrimento al termine. I browser scelgono quindi la posizione finale più appropriata in base alle caratteristiche dell'operazione di scorrimento, al layout e alla visibilità del contenitore di scorrimento e ai dettagli delle posizioni di snap, quindi animano in modo fluido il movimento. Tornando all'esempio precedente, quando l'utente termina lo scorrimento del carosello, l'immagine visibile si blocca in posizione. Nessuna regolazione dello scorrimento necessaria tramite JavaScript.

Esempio di utilizzo dello scorrimento controllato CSS con un carosello di immagini.
Esempio di utilizzo dello scorrimento CSS con un carosello di immagini. In questo caso, lo scorrimento agganciato assicura che alla fine dello scorrimento il centro orizzontale di un'immagine sia allineato al centro orizzontale del contenitore di scorrimento.

CSS Scroll Snap

Lo scorrimento con allineamento è l'azione di 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 contenitore di scorrimento può essere attivato per lo scorrimento con snap utilizzando la proprietà scroll-snap-type. Indica al browser di considerare lo scorrimento di questo container in base alle posizioni di snap prodotte dai relativi elementi secondari. scroll-snap-type determina l'asse su cui avviene lo scorrimento: x, y o both e la rigidità dello snapping: mandatory, proximity. Ne parleremo più avanti.

Una posizione di snap può essere prodotta dichiarando un allineamento desiderato su un elemento. Questa posizione è l'offset di scorrimento in corrispondenza del quale il contenitore di scorrimento antenato più vicino e l'elemento sono allineati come specificato per l'asse indicato. I seguenti allineamenti sono possibili su ogni asse: start, end, center.

Un allineamento start indica che il bordo iniziale dell'area di scorrimento dello snap deve essere allineato al bordo iniziale dell'area di snap dell'elemento. Analogamente, gli allineamenti end e center indicano che il bordo finale o il centro del contenitore di scorrimento deve essere a filo con il bordo finale o il centro 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 scorrimento controllato è un carosello di immagini. Ad esempio, per creare un carosello di immagini orizzontale che si blocca su ogni immagine mentre scorri, 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 il blocco 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 snap sono associate a un elemento, l'algoritmo di snapping può essere intelligente su quando e come eseguire lo snap in base all'elemento e alle dimensioni del contenitore di scorrimento. Ad esempio, considera il caso in cui un'immagine è più grande del carosello. Un algoritmo di snapping ingenuo potrebbe impedire all'utente di spostarsi per vedere l'immagine completa. Tuttavia, la specifica richiede che le implementazioni rilevino questo caso e consentano all'utente di scorrere liberamente all'interno dell'immagine, con scatti solo ai bordi.

Esempio: una pagina di prodotto con percorso

Un altro caso comune che può trarre vantaggio dallo scorrimento controllato sono le pagine con più sezioni logiche da scorrere verticalmente, ad esempio una tipica pagina di prodotto. scroll-snap-type: y proximity; è più adatto a casi come questo. Non interferisce quando un utente scorre fino al centro di una determinata sezione, ma si blocca e attira l'attenzione su una nuova sezione quando 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 del prodotto ha un'intestazione superiore con posizione fissa. Il design prevedeva anche che una parte della sezione superiore rimanesse visibile quando il contenitore di scorrimento veniva bloccato, in modo da fornire agli utenti un indizio visivo sui contenuti precedenti.

La proprietà scroll-padding è una nuova proprietà CSS che può essere utilizzata per regolare la regione visibile effettiva del contenitore di scorrimento o dello snapport, che viene utilizzato per calcolare gli allineamenti dello scorrimento rapido. La proprietà definisce un rientro rispetto alla casella di riempimento del contenitore di scorrimento. Nel nostro esempio, è stato aggiunto un 15vh rientro aggiuntivo nella parte superiore, che indica al browser di considerare una posizione inferiore, 15vh sotto il bordo superiore del contenitore di scorrimento, come bordo iniziale verticale per lo scorrimento agganciato. Durante l'allineamento, il bordo iniziale dell'elemento di destinazione dell'allineamento diventerà a filo con questa nuova posizione, lasciando spazio sopra.

La proprietà scroll-margin definisce l'importo dell'inizio utilizzato per regolare la casella effettiva del target di snap in modo simile al funzionamento di scroll-padding sul container di scorrimento con snap.

Potresti aver notato che queste due proprietà non contengono la parola "snap". Ciò è intenzionale, in quanto modificano effettivamente la casella per tutte le operazioni di scorrimento pertinenti e non solo lo scorrimento rapido. Ad esempio, Chrome li prende in considerazione quando calcola le dimensioni della pagina per le operazioni di scorrimento della paginazione, 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

Lo scorrimento agganciato si verifica 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 snapping appropriata per trovare la posizione finale. Pertanto, non è necessario che lo script utente esegua calcoli manuali per lo snapping.

Scorrimento fluido

Lo scorrimento uniforme controlla il comportamento di un'operazione di scorrimento programmatica, mentre lo scorrimento con blocco determina la destinazione. Poiché controllano aspetti ortogonali dello scorrimento, possono essere utilizzati insieme e completarsi a vicenda.

Comportamento di overscroll

L'API Overscroll Behavior controlla la concatenazione dello scorrimento su più elementi e non è influenzata dallo scorrimento rapido.

Avvertenze e best practice

Evita di utilizzare l'allineamento forzato quando gli elementi target sono molto distanti tra loro. Ciò può causare l'inaccessibilità dei contenuti tra le posizioni di snap.

In molti casi, lo scorrimento agganciato può essere aggiunto come miglioramento senza la necessità di rilevare le funzionalità. Se necessario, utilizza @supports o CSS.supports per rilevare il supporto di CSS Scroll Snap. Evita di utilizzare scroll-snap-type, 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 all'offset di scorrimento richiesto. Lo scorrimento con blocco potrebbe regolare l'offset di scorrimento al termine dello scorrimento programmatico. Tieni presente che questo non era un buon presupposto anche prima dello scorrimento agganciato, poiché lo scorrimento potrebbe essere stato interrotto per altri motivi, ma è particolarmente vero con lo scorrimento agganciato.

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. I prossimi lavori si concentreranno su scroll-snap, tra cui:

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