Neem de controle over uw scrollen en pas de pull-to-refresh- en overflow-effecten aan

TL; DR

Met de CSS-eigenschap overscroll-behavior kunnen ontwikkelaars het standaard overflow-scrollgedrag van de browser overschrijven wanneer ze de boven-/onderkant van de inhoud bereiken. Gebruiksscenario's zijn onder meer het uitschakelen van de pull-to-refresh-functie op mobiel, het verwijderen van overscroll-glow en rubberbanding-effecten, en het voorkomen dat pagina-inhoud scrollt wanneer deze zich onder een modale/overlay bevindt.

Achtergrond

Scrollgrenzen en scrollketens

Scroll-chaining op Chrome Android.

Scrollen is een van de meest fundamentele manieren om met een pagina te communiceren, maar bepaalde UX-patronen kunnen lastig zijn om mee om te gaan vanwege het eigenzinnige standaardgedrag van de browser. Neem als voorbeeld een app-lade met een groot aantal items waar de gebruiker mogelijk doorheen moet scrollen. Wanneer ze de bodem bereiken, stopt de overloopcontainer met scrollen omdat er geen inhoud meer is om te consumeren. Met andere woorden: de gebruiker bereikt een "scrollgrens". Maar kijk eens wat er gebeurt als de gebruiker blijft scrollen. De inhoud achter de lade begint te scrollen ! Het scrollen wordt overgenomen door de bovenliggende container; de hoofdpagina zelf in het voorbeeld.

Blijkt dat dit gedrag 'scroll chaining' wordt genoemd; het standaardgedrag van de browser bij het scrollen door inhoud. Vaak is de standaardinstelling best aardig, maar soms is deze niet wenselijk of zelfs onverwacht. Bepaalde apps willen mogelijk een andere gebruikerservaring bieden wanneer de gebruiker een scrollgrens bereikt.

Het pull-to-refresh-effect

Pull-to-refresh is een intuïtief gebaar dat populair wordt gemaakt door mobiele apps zoals Facebook en Twitter. Door een sociale feed naar beneden te halen en vrij te geven, ontstaat er nieuwe ruimte voor het laden van recentere berichten. Deze specifieke UX is zelfs zo populair geworden dat mobiele browsers zoals Chrome op Android hetzelfde effect hebben overgenomen. Als u bovenaan de pagina naar beneden veegt, wordt de hele pagina vernieuwd:

Twitter's aangepaste pull-to-refresh
bij het vernieuwen van een feed in hun PWA.
De native pull-to-refresh-actie van Chrome Android
ververst de hele pagina.

Voor situaties zoals de Twitter PWA kan het zinvol zijn om de native pull-to-refresh-actie uit te schakelen. Waarom? In deze app wil je waarschijnlijk niet dat de gebruiker per ongeluk de pagina vernieuwt. Er is ook de mogelijkheid om een ​​dubbele vernieuwingsanimatie te zien! Als alternatief kan het leuker zijn om de actie van de browser aan te passen, zodat deze beter aansluit bij de branding van de site. Het ongelukkige deel is dat dit soort aanpassingen lastig uit te voeren was. Ontwikkelaars schrijven uiteindelijk onnodig JavaScript, voegen niet-passieve aanraakluisteraars toe (die het scrollen blokkeren) of plakken de hele pagina in een 100vw/vh <div> (om te voorkomen dat de pagina overloopt). Deze oplossingen hebben goed gedocumenteerde negatieve effecten op de scrollprestaties.

Wij kunnen het beter doen!

Introductie van overscroll-behavior

De eigenschap overscroll-behavior is een nieuwe CSS-functie die het gedrag regelt van wat er gebeurt als u over een container heen scrollt (inclusief de pagina zelf). Je kunt het gebruiken om scroll-chaining te annuleren, de pull-to-refresh-actie uit te schakelen/aan te passen, rubberbanding-effecten op iOS uit te schakelen (wanneer Safari overscroll-behavior implementeert) en meer. Het beste is dat het gebruik van overscroll-behavior geen nadelige invloed heeft op de paginaprestaties, zoals de hacks die in de intro worden genoemd!

De eigenschap heeft drie mogelijke waarden:

  1. automatisch - Standaard. Scrolls die afkomstig zijn van het element kunnen zich voortplanten naar voorouderelementen.
  2. bevatten - voorkomt scroll-chaining. Scrolls verspreiden zich niet naar voorouders, maar lokale effecten binnen het knooppunt worden getoond. Bijvoorbeeld het overscroll-gloeieffect op Android of het rubberen bandeffect op iOS, dat de gebruiker waarschuwt wanneer hij een scrollgrens heeft bereikt. Opmerking : het gebruik van overscroll-behavior: contain op het html -element voorkomt overscroll-navigatieacties.
  3. geen - hetzelfde als contain , maar het voorkomt ook overscroll-effecten binnen het knooppunt zelf (bijvoorbeeld Android-overscroll-gloed of iOS-rubberbanding).

Laten we enkele voorbeelden bekijken om te zien hoe overscroll-behavior kunt gebruiken.

Voorkom dat scrolls uit een vast positie-element ontsnappen

Het chatbox-scenario

Inhoud onder het chatvenster scrollt ook :(

Overweeg een vast geplaatste chatbox die onderaan de pagina staat. De bedoeling is dat de chatbox een op zichzelf staand onderdeel is en los van de inhoud erachter scrollt. Vanwege scroll-chaining begint het document echter te scrollen zodra de gebruiker het laatste bericht in de chatgeschiedenis bezoekt.

Voor deze app is het passender om scrolls die afkomstig zijn uit de chatbox binnen de chat te laten blijven. We kunnen dat mogelijk maken door overscroll-behavior: contain toe te voegen aan het element dat de chatberichten bevat:

#chat .msgs {
  overflow: auto;
  overscroll-behavior: contain;
  height: 300px;
}

In wezen creëren we een logische scheiding tussen de scrollcontext van de chatbox en de hoofdpagina. Het eindresultaat is dat de hoofdpagina blijft staan ​​wanneer de gebruiker de boven-/onderkant van de chatgeschiedenis bereikt. Scrolls die in de chatbox beginnen, verspreiden zich niet naar buiten.

Het pagina-overlayscenario

Een andere variant van het 'underscroll'-scenario is wanneer u inhoud ziet scrollen achter een overlay met een vaste positie . Een dood weggeef- overscroll-behavior is op zijn plaats! De browser probeert behulpzaam te zijn, maar zorgt er uiteindelijk voor dat de site er buggy uitziet.

Voorbeeld - modaal met en zonder overscroll-behavior: contain :

Voor : de pagina-inhoud schuift onder de overlay.
Na : de pagina-inhoud schuift niet onder de overlay.

Pull-to-refresh uitschakelen

Het uitschakelen van de pull-to-refresh-actie is een enkele regel CSS . Voorkom gewoon scroll-chaining op het gehele viewport-definiërende element. In de meeste gevallen is dat <html> of <body> :

body {
  /* Disables pull-to-refresh but allows overscroll glow effects. */
  overscroll-behavior-y: contain;
}

Met deze eenvoudige toevoeging repareren we de dubbele pull-to-refresh-animaties in de chatbox-demo en kunnen we in plaats daarvan een aangepast effect implementeren dat een nettere laadanimatie gebruikt. De hele inbox vervaagt ook terwijl de inbox wordt vernieuwd:

Voor
Na

Hier is een fragment van de volledige code :

<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>

Overscroll-gloei- en elastiekeffecten worden uitgeschakeld

Om het bounce-effect uit te schakelen bij het raken van een scrollgrens, gebruik je overscroll-behavior-y: none :

body {
  /* Disables pull-to-refresh and overscroll glow effect.
     Still keeps swipe navigations. */
  overscroll-behavior-y: none;
}
Voor : het raken van de scrollgrens laat een gloed zien.
Na : gloed uitgeschakeld.

Volledige demo

Alles bij elkaar genomen maakt de volledige chatbox-demo gebruik van overscroll-behavior om een ​​aangepaste pull-to-refresh-animatie te creëren en te voorkomen dat scrolls uit de chatbox-widget ontsnappen. Dit zorgt voor een optimale gebruikerservaring die lastig te realiseren zou zijn geweest zonder CSS- overscroll-behavior .

Bekijk demo | Bron