TL;DR
La proprietà CSS overscroll-behavior consente agli sviluppatori di eseguire l'override del comportamento di scorrimento dell'overflow predefinito del browser quando raggiungono la parte superiore/inferiore dei contenuti. I casi d'uso includono la disattivazione della funzionalità di pull to refresh sui dispositivi mobili, la rimozione degli effetti di overscroll glow e rubberbanding e la prevenzione dello scorrimento dei contenuti della pagina quando si trovano sotto un overlay/una finestra modale.
Sfondo
Limiti di scorrimento e concatenamento dello scorrimento
Lo scorrimento è uno dei modi più fondamentali per interagire con una pagina, ma alcuni pattern UX possono essere difficili da gestire a causa dei comportamenti predefiniti particolari del browser. Ad esempio, prendi un riquadro a scomparsa delle app con un numero elevato di elementi che l'utente potrebbe dover scorrere. Quando raggiungono la parte inferiore, il contenitore di overflow interrompe lo scorrimento perché non ci sono più contenuti da visualizzare. In altre parole, l'utente raggiunge un "limite di scorrimento". Ma nota cosa succede se l'utente continua a scorrere. I contenuti dietro il riquadro a scomparsa iniziano a scorrere. Lo scorrimento viene assunto dal container principale, ovvero la pagina principale stessa nell'esempio.
Questo comportamento è chiamato concatenamento dello scorrimento ed è il comportamento predefinito del browser durante lo scorrimento dei contenuti. Spesso l'impostazione predefinita è piuttosto buona, ma a volte non è quella desiderata o è addirittura imprevista. Alcune app potrebbero voler offrire un'esperienza utente diversa quando l'utente raggiunge un limite di scorrimento.
L'effetto pull to refresh
Il pull to refresh è un gesto intuitivo reso popolare da app mobile come Facebook e Twitter. Se trascini verso il basso un feed social e lo rilasci, crei un nuovo spazio per caricare i post più recenti. In effetti, questa particolare UX è diventata così popolare che i browser mobile come Chrome su Android hanno adottato lo stesso effetto. Scorrendo verso il basso nella parte superiore della pagina, l'intera pagina viene aggiornata:
quando si aggiorna un feed nella sua PWA.
aggiorna l'intera pagina.
Per situazioni come la PWA di Twitter, potrebbe avere senso disattivare l'azione di pull to refresh nativa. Perché? In questa app, probabilmente non vuoi che l'utente aggiorni accidentalmente la pagina. C'è anche la possibilità di vedere un'animazione di aggiornamento doppia. In alternativa, potrebbe essere più utile personalizzare l'azione del browser, allineandola maggiormente al branding del sito. La parte sfortunata è che questo tipo di personalizzazione è stato difficile da realizzare. Gli sviluppatori finiscono per scrivere JavaScript non necessario, aggiungere listener touch non passivi (che bloccano lo scorrimento) o inserire l'intera pagina in un <div> 100vw/vh (per impedire l'overflow della pagina). Queste soluzioni alternative hanno effetti negativi ben documentati sulle prestazioni di scorrimento.
Possiamo fare di meglio.
Ti presentiamo overscroll-behavior
La proprietà overscroll-behavior è una nuova funzionalità CSS che controlla il comportamento di ciò che accade quando esegui lo scorrimento eccessivo di un container (inclusa la pagina stessa). Puoi utilizzarla per annullare il concatenamento dello scorrimento, disattivare/personalizzare l'azione di pull to refresh, disattivare gli effetti di rubberbanding su iOS (quando Safari implementa overscroll-behavior) e altro ancora.
La parte migliore è che l'utilizzo di overscroll-behavior non influisce negativamente sulle prestazioni della pagina come gli hack menzionati nell'introduzione.
La proprietà accetta tre possibili valori:
- auto: predefinito. Gli scorrimenti che hanno origine sull'elemento possono propagarsi agli elementi principali.
- contain: impedisce il concatenamento dello scorrimento. Gli scorrimenti non si propagano agli elementi precedenti, ma vengono mostrati gli effetti locali all'interno del nodo. Ad esempio, l'effetto di overscroll glow su Android o l'effetto di rubberbanding su iOS, che avvisa l'utente quando ha raggiunto un limite di scorrimento. Nota: l'utilizzo di
overscroll-behavior: containsull'elementohtmlimpedisce le azioni di navigazione con overscroll. - none: come
contain, ma impedisce anche gli effetti di overscroll all'interno del nodo stesso (ad es. l'effetto di overscroll di Android o l'effetto di rimbalzo di iOS).
Vediamo alcuni esempi per capire come utilizzare overscroll-behavior.
Impedisci lo scorrimento di un elemento con posizione fissa
Lo scenario della chatbox
Considera una finestra di chat con posizione fissa nella parte inferiore della pagina. L'intenzione è che la chatbox sia un componente autonomo e che scorra separatamente dai contenuti dietro di essa. Tuttavia, a causa del concatenamento dello scorrimento, il documento inizia a scorrere non appena l'utente raggiunge l'ultimo messaggio nella cronologia chat.
Per questa app, è più appropriato che gli scorrimenti che hanno origine all'interno della chatbox rimangano all'interno della chat. Possiamo farlo aggiungendo overscroll-behavior: contain all'elemento che contiene i messaggi chat:
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
In sostanza, stiamo creando una separazione logica tra il contesto di scorrimento della chatbox e la pagina principale. Il risultato finale è che la pagina principale rimane ferma quando l'utente raggiunge l'inizio o la fine della cronologia chat. Gli scorrimenti che iniziano nella casella di chat non si propagano all'esterno.
Scenario di overlay della pagina
Un'altra variante dello scenario di "scorrimento sotto" si verifica quando vedi i contenuti scorrere dietro un overlay con posizione fissa. Un indizio evidente
overscroll-behavior è d'obbligo! Il browser sta cercando di essere utile, ma finisce per far sembrare il sito difettoso.
Esempio: finestra modale con e senza overscroll-behavior: contain:
Disattivazione della funzionalità pull to refresh
La disattivazione dell'azione di pull to refresh è una singola riga di CSS. Basta impedire il concatenamento dello scorrimento sull'intero elemento che definisce l'area visibile. Nella maggior parte dei casi, si tratta di
<html> o <body>:
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
Con questa semplice aggiunta, correggiamo le doppie animazioni di pull to refresh nella demo della chatbox e possiamo invece implementare un effetto personalizzato che utilizza un'animazione di caricamento più ordinata. Anche l'intera posta in arrivo viene sfocata durante l'aggiornamento:
Ecco uno snippet del codice completo:
<style>
body.refreshing #inbox {
filter: blur(1px);
touch-action: none; /* prevent scrolling */
}
body.refreshing .refresher {
transform: translate3d(0,150%,0) scale(1);
z-index: 1;
}
.refresher {
--refresh-width: 55px;
pointer-events: none;
width: var(--refresh-width);
height: var(--refresh-width);
border-radius: 50%;
position: absolute;
transition: all 300ms cubic-bezier(0,0,0.2,1);
will-change: transform, opacity;
...
}
</style>
<div class="refre>she<r"
div class=&qu><ot;l>oad<ing-bar"/div
div>< cla>ss=<"loading-bar"></div>
<div class="loading><-bar>&<quot>;/<div
div class=&q><uot;loading><-bar&quo>t;</div
/>div
section id="inbox"!-- msgs --/section
script
let _startY;
const inbox = document.querySel>ector('#inbox');
inbox.addEventListener('touchstart', e = {
_startY = e.touches>[0].pageY;
}, {passive: true});
inbox.addEventListener('touchmove', e = {
const y = e.touches[0].pageY;
// Activate custom pull-to-refresh effects when at the top of the container&&
> // and &&user is scrolling up.
if (document.scrollingElement.scrollTop === 0 y _startY
!document.body.class<List.co>ntains('refreshing')) {
// refresh inbox.
}
}, {passive: true});
/script
Disattivazione degli effetti di overscroll glow e rubberbanding
Per disattivare l'effetto di rimbalzo quando si raggiunge un limite di scorrimento, utilizza
overscroll-behavior-y: none:
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
Demo completa
Mettendo tutto insieme, la demo completa della chatbox utilizza overscroll-behavior per creare un'animazione di pull to refresh personalizzata e impedire che gli scorrimenti escano dal widget della chatbox. In questo modo, l'esperienza utente è ottimale, cosa che sarebbe stata difficile da ottenere senza CSS overscroll-behavior.