TL;DR
La proprietà CSS overscroll-behavior
consente agli sviluppatori di ignorare il comportamento di scorrimento per i contenuti in eccesso predefinito del browser quando si raggiunge la parte superiore/inferiore dei contenuti. I casi d'uso includono la disattivazione della funzionalità di aggiornamento con trazione su dispositivi mobili, la rimozione dell'effetto di sfarfallio e di rallentamento dello scorrimento e l'impedimento dello scorrimento dei contenuti della pagina quando si trovano sotto un popup/overlay.
Sfondo
Limiti di scorrimento e accoppiamento di scorrimenti
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 insoliti del browser. Ad esempio, prendi un riquadro delle app con un numero elevato di elementi che l'utente potrebbe dover scorrere. Quando raggiunge il fondo, il contenitore overflow interrompe lo scorrimento perché non ci sono più contenuti da consumare. In altre parole, l'utente raggiunge un "limite di scorrimento". Ma notiamo cosa succede se l'utente continua a scorrere. I contenuti dietro il riquadro inizia a scorrere. Lo scorrimento viene assunto dal contenitore principale, ovvero la pagina principale stessa nell'esempio.
A quanto pare, questo comportamento si chiama catena di scorrimento ed è il comportamento predefinito del browser quando si scorrono i contenuti. Spesso il valore predefinito è abbastanza buono, ma talvolta non è auspicabile o addirittura imprevisto. Alcune app potrebbero voler offrire un'esperienza utente diversa quando l'utente raggiunge un confine di scorrimento.
L'effetto di scorrimento per aggiornare
Il gesto di scorrimento per aggiornare è un gesto intuitivo reso popolare da app mobile come Facebook e Twitter. Se scorri verso il basso un feed social e rilasci, viene creato un nuovo spazio per il caricamento dei post più recenti. In effetti, questa particolare UX è diventata così popolare che i browser mobile come Chrome su Android hanno adottato lo stesso effetto. Se scorri verso il basso nella parte superiore della pagina, l'intera pagina viene aggiornata:
Per situazioni come la PWA di Twitter, potrebbe essere opportuno disattivare l'azione di aggiornamento con scorrimento nativa. Perché? In questa
app, probabilmente non vuoi che l'utente aggiorni accidentalmente la pagina. Inoltre, c'è la possibilità di vedere un'animazione di aggiornamento doppio. In alternativa, potrebbe essere più piacevole personalizzare l'azione del browser, allineandola maggiormente al branding del sito. Purtroppo, questo tipo di personalizzazione è stato difficile da realizzare. Gli sviluppatori finiscono per scrivere codice JavaScript non necessario, aggiungere metodi di ascolto dei tocchi non passivi (che bloccano lo scorrimento) o inserire l'intera pagina in un elemento 100vw/vh<div>
(per evitare che la pagina fuoriesca). Queste soluzioni alternative hanno effetti negativi ben documentati sul rendimento dello scorrimento.
Possiamo fare di meglio.
Ti presentiamo overscroll-behavior
La proprietà overscroll-behavior
è una nuova funzionalità CSS che controlla il comportamento che si verifica quando scorri oltre un contenitore (inclusa la pagina stessa). Puoi utilizzarlo per annullare la catena di scorrimento, disattivare/personalizzare l'azione di scorrimento verso l'alto per aggiornare, disattivare gli effetti di rallentamento su iOS (quando Safari implementa overscroll-behavior
) e altro ancora.
La parte migliore è che l'utilizzo di overscroll-behavior
non influisce negativamente sul rendimento della pagina, come gli hack menzionati nell'introduzione.
La proprietà può avere tre valori possibili:
- auto: valore predefinito. Le scorrimenti che hanno origine nell'elemento possono propagarsi agli elementi ancestrali.
- contain: impedisce la concatenazione dello scorrimento. I scorrimenti non si propagano agli antenati, ma vengono mostrati gli effetti locali all'interno del nodo. Ad esempio, l'effetto di sfarfallamento scorrimento su Android o l'effetto di rallentamento su iOS che avvisa l'utente quando raggiunge un confine di scorrimento. Nota: l'utilizzo di
overscroll-behavior: contain
nell'elementohtml
impedisce le azioni di navigazione con scorrimento eccessivo. - none: come
contain
, ma impedisce anche gli effetti di scorrimento eccessivo all'interno del nodo stesso (ad es. l'effetto bagliore di scorrimento eccessivo di Android o il rallentamento di iOS).
Vediamo alcuni esempi per capire come utilizzare overscroll-behavior
.
Impedire che i movimenti di scorrimento escano da un elemento in posizione fissa
Lo scenario della finestra della chat
Prendi in considerazione una casella di chat posizionata in modo fisso nella parte inferiore della pagina. L'intenzione è che la casella della chat sia un componente autonomo e scorra separatamente dai contenuti che la seguono. Tuttavia, a causa della catena di scorrimento, il documento inizia a scorrere non appena l'utente raggiunge l'ultimo messaggio nella chat storia.
Per questa app, è più appropriato che le scorribande che hanno origine all'interno della chatbox rimangano all'interno della chat. Possiamo farlo aggiungendo
overscroll-behavior: contain
all'elemento che contiene i messaggi della chat:
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
In sostanza, stiamo creando una separazione logica tra il contesto scorrevole della finestra della chat e la pagina principale. Il risultato finale è che la pagina principale rimane invariata quando l'utente raggiunge la parte superiore/inferiore della cronologia chat. Le scorribande che iniziano nella chatbox non si propagano.
Scenario di overlay della pagina
Un'altra variante dello scenario "sotto scorrimento" si verifica quando i contenuti scorrono dietro un overlay con posizione fissa. Un'offerta imperdibile
overscroll-behavior
è in corso. Il browser sta cercando di essere utile, ma
finisce per far sembrare il sito buggato.
Esempio: finestra modale con e senza overscroll-behavior: contain
:
Disattivare la funzionalità di aggiornamento con un movimento verso il basso
La disattivazione dell'azione di aggiornamento con scorrimento è una singola riga di CSS. Basta impedire la catena di scorrimento nell'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 animazioni di aggiornamento con doppio scorrimento nella demo della casella di chat e possiamo 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="refresher">
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
</div>
<section id="inbox"><!-- msgs --></section>
<script>
let _startY;
const inbox = document.querySelector('#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.classList.contains('refreshing')) {
// refresh inbox.
}
}, {passive: true});
</script>
Disattivazione degli effetti di sfarfallio e effetto gomma di overscroll
Per disattivare l'effetto di rimbalzo quando viene raggiunto un confine 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 casella di chat utilizza overscroll-behavior
per creare un'animazione personalizzata per l'aggiornamento tramite trascinamento e per impedire che le operazioni di scorrimento escano dal widget della casella di chat. In questo modo viene offerta un'esperienza utente ottimale che sarebbe stata difficile da ottenere senza CSSoverscroll-behavior
.