Assumi il controllo dello scorrimento personalizzando gli effetti pull-to-refresh e overflow

TL;DR

La proprietà CSS overscroll-behavior consente agli sviluppatori di eseguire l'override della comportamento predefinito del browser quando si raggiunge la parte superiore o inferiore del 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 e concatenamento degli scorrimenti

Concatenamento con lo scorrimento su Chrome per Android.

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, consideriamo un riquadro a scomparsa delle app con un gran numero di gli 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 offrono un'esperienza utente diversa quando l'utente raggiunge il limite di scorrimento.

L'effetto di scorrimento per aggiornare

Pull-to-refresh è un gesto intuitivo diffuso 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. Infatti, questa particolare UX ha sono diventate talmente popolari che i browser mobile come Chrome su Android hanno adottato lo stesso effetto. Se scorri verso il basso nella parte superiore della pagina, viene aggiornata l'intera pagina:

Pull-to-refresh personalizzato di Twitter
durante l'aggiornamento di un feed in la propria PWA.
L'azione nativa di aggiornamento pull-to-refresh di Chrome Android
aggiorna l'intera .

Per situazioni come la PWA di Twitter, potrebbe essere utile disattivare l'azione nativa "pull-to-refresh". Perché? In questa app, probabilmente non vuoi che l'utente aggiorni accidentalmente la pagina. C'è e la possibilità di visualizzare un'animazione di doppio aggiornamento. In alternativa, migliorare la personalizzazione dell'azione del browser, allineandola meglio alla branding. Purtroppo, questo tipo di personalizzazione è stato difficile da realizzare. Gli sviluppatori finiscono per scrivere codice JavaScript non necessario, aggiungere listener touch 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 negativo ben documentato effetti sullo 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 fai lo scorrimento eccessivo di un contenitore (incluso il pagina stessa). Puoi utilizzarla per annullare il concatenamento, disattivare/personalizzare l'azione pull-to-refresh, disattiva gli effetti del rubberbanding su iOS (quando Safari implementa overscroll-behavior) e altro ancora. La parte migliore è che l'uso di overscroll-behavior non influisce negativamente come le prestazioni della pagina, come i trucchi menzionati nell'introduzione.

La proprietà può avere tre valori possibili:

  1. auto: valore predefinito. Le scorribande che hanno origine nell'elemento possono propagarsi agli elementi ancestrali.
  2. contain: impedisce il concatenamento dello scorrimento. I scorrimenti non si propagano agli antenati, ma vengono mostrati gli effetti locali all'interno del nodo. Ad esempio, l'effetto di sfarfallio con scorrimento su Android o l'effetto di elasticità su iOS che avvisa l'utente quando raggiunge un limite di scorrimento. Nota: l'utilizzo di overscroll-behavior: contain nell'elemento html impedisce le azioni di navigazione con scorrimento eccessivo.
  3. none: uguale a contain ma impedisce anche gli effetti overscroll all'interno il nodo stesso (ad es. bagliore overscroll per Android o rubberbanding di iOS).

Vediamo alcuni esempi per capire come utilizzare overscroll-behavior.

Impedisci agli scorrimenti di uscire da un elemento con posizione fissa

Lo scenario della finestra della chat

Anche i contenuti sotto la finestra della chat scorrono :(

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 di 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 in posizione l'utente raggiunge la parte superiore o inferiore della cronologia chat. Scorrimenti che iniziano tra la casella della chat non si propaga.

Scenario overlay di pagina

Un'altra variante dello scenario "sotto scorrimento" si verifica quando i contenuti scorrono dietro un overlay con posizione fissa. Un regalo davvero speciale overscroll-behavior è in arrivo. Il browser sta cercando di essere utile, finisce per far sì che il sito sembri insidioso.

Esempio: finestra modale con e senza overscroll-behavior: contain:

Prima: i contenuti della pagina scorrono sotto l'overlay.
Dopo: i contenuti della pagina non scorrono sotto l'overlay.

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:

Prima
Dopo

Ecco uno snippet delle 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 di rallentamento durante lo scorrimento

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;
}
Prima: quando viene raggiunto il limite di scorrimento, viene visualizzato un bagliore.
Dopo: l'effetto bagliore è disattivato.

Demo completa

Riassumendo, l'intera usi della chatbox demo overscroll-behavior per creare un'animazione pull-to-refresh personalizzata e disabilitare gli scorrimenti per evitare l'interpretazione letterale al widget della chatbox. Ciò fornisce un'ottimizzazione un'esperienza utente difficile da ottenere senza CSS overscroll-behavior.

Visualizza la demo | Codice sorgente