Behalte die Kontrolle über das Scrollen – mit der Option „Zum Aktualisieren ziehen“ und „Überlauf“ kannst du die Effekte anpassen

Kurzfassung

Mit der Eigenschaft CSS overscroll-behavior können Entwickler das standardmäßige Scrollverhalten des Browsers beim Überlauf überschreiben, wenn sie den oberen oder unteren Rand des Inhalts erreichen. Zu den Anwendungsfällen gehören das Deaktivieren der Funktion zum Aktualisieren zum Aktualisieren auf Mobilgeräten, das Entfernen des Overscroll-Leuchten und der Gummibanding-Effekte sowie das Verhindern des Scrollens des Seiteninhalts, wenn er sich unter einem modalen oder Overlay befindet.

Hintergrund

Scrollgrenzen und Scroll-Verkettung

Scrollverkettung unter Chrome Android.

Scrollen ist eine der grundlegendsten Methoden zur Interaktion mit einer Seite. Aufgrund des ungewöhnlichen Standardverhaltens des Browsers kann das Umgang mit bestimmten UX-Mustern jedoch schwierig sein. Nehmen wir als Beispiel eine App-Leiste mit einer großen Anzahl von Elementen, durch die der Nutzer möglicherweise scrollen muss. Wenn sie den unteren Rand erreichen, stoppt das Scrollen des Überlaufcontainers, da kein weiterer Inhalt vorhanden ist. Mit anderen Worten: Der Nutzer erreicht eine Scroll-Grenze. Beachten Sie jedoch, was passiert, wenn der Nutzer weiterscrollt. Der Inhalt hinter der Leiste beginnt zu scrollen. Das Scrollen wird vom übergeordneten Container übernommen. In diesem Beispiel ist das die Hauptseite.

Wie sich herausstellt, wird dieses Verhalten als Scrollverkettung bezeichnet. Das ist das Standardverhalten des Browsers beim Scrollen von Inhalten. Oft ist die Standardeinstellung schön, aber manchmal nicht erwünscht oder sogar unerwartet. Bestimmte Apps möchten möglicherweise eine andere Nutzererfahrung bieten, wenn der Nutzer eine Scroll-Grenze erreicht.

Der Effekt „Zum Aktualisieren ziehen“

„Zum Aktualisieren ziehen“ ist eine intuitive Geste, die von mobilen Apps wie Facebook und Twitter bekannt wird. Wenn du einen sozialen Feed nach unten aufrufst und ihn freigibst, wird ein neuer Platz zum Laden neuerer Beiträge geschaffen. Tatsächlich ist diese spezielle UX so beliebt, dass mobile Browser wie Chrome unter Android denselben Effekt haben. Wenn Sie oben auf der Seite nach unten wischen, wird die gesamte Seite aktualisiert:

Die benutzerdefinierte Funktion „Zum Aktualisieren nach unten ziehen“ von Twitter
, wenn ein Feed in der PWA aktualisiert wird.
Die native Chrome-Android-Aktion „Zum Aktualisieren nach unten ziehen“
aktualisiert die gesamte Seite.

Für Situationen wie die PWA von Twitter kann es sinnvoll sein, die native Aktion zum Aktualisieren nach unten zu deaktivieren. Warum? In dieser App möchten Sie wahrscheinlich nicht, dass der Nutzer versehentlich die Seite aktualisiert. Es kann auch zu einer doppelten Aktualisierungsanimation kommen. Alternativ kann es sinnvoller sein, die Aktion des Browsers anzupassen und ihn besser auf das Branding der Website auszurichten. Leider ist es schwierig, diese Art der Anpassung umzusetzen. Entwickler schreiben am Ende unnötiges JavaScript, fügen nicht-passive Touch-Listener hinzu, die das Scrollen blockieren, oder belassen die gesamte Seite in einem <div>-Format (100 vw/vh), damit die Seite nicht überläuft. Diese Behelfslösungen haben gut dokumentierte negative Auswirkungen auf die Scrollleistung.

Das können wir besser!

Jetzt neu: overscroll-behavior

Das Attribut overscroll-behavior ist eine neue CSS-Funktion, mit der das Verhalten beim Überscrollen eines Containers (einschließlich der Seite selbst) gesteuert wird. Sie können sie verwenden, um die Scroll-Verkettung abzubrechen, die Aktion zum Aktualisieren durch Pull zu deaktivieren/anpassen, die Gummibanding-Effekte unter iOS zu deaktivieren (wenn Safari overscroll-behavior implementiert) und vieles mehr. Das Beste daran ist, dass die Verwendung von overscroll-behavior die Seitenleistung nicht beeinträchtigt, wie in der Einführung beschrieben.

Für das Attribut sind drei mögliche Werte möglich:

  1. auto: Die Standardeinstellung. Scrollvorgänge, die von einem Element ausgehen, können zu Ancestor-Elementen weitergegeben werden.
  2. contain: Verhindert die Scroll-Verkettung. Scrollvorgänge werden nicht an Ancestors weitergegeben, aber lokale Effekte innerhalb des Knotens werden angezeigt. Beispielsweise der Overscroll-Glow-Effekt unter Android oder der Gummibanding-Effekt unter iOS, durch den der Nutzer benachrichtigt wird, wenn er eine Scroll-Grenze erreicht hat. Hinweis: Durch die Verwendung von overscroll-behavior: contain für das Element html werden Overscroll-Navigationsaktionen verhindert.
  3. none: Entspricht contain, verhindert aber auch Overscroll-Effekte innerhalb des Knotens selbst (z.B. Android-Overscroll-Leuchten oder iOS-Gummibanding).

Sehen wir uns ein paar Beispiele für die Verwendung von overscroll-behavior an.

Verhindern, dass Scrollvorgänge in einem Element mit fester Position umgangen werden

Das Chatbox-Szenario

Der Inhalt unter dem Chatfenster wird ebenfalls gescrollt :(

Nehmen wir ein fest positioniertes Chatfeld unten auf der Seite. Die Absicht besteht darin, dass das Chatfeld eine eigenständige Komponente ist und vom Inhalt dahinter getrennt scrollt. Aufgrund der Scroll-Verkettung beginnt das Dokument jedoch, sobald der Nutzer auf die letzte Nachricht im Chatverlauf stößt.

Für diese App ist es sinnvoller, dass Scrollvorgänge, die von der Chatbox ausgehen, innerhalb des Chats verbleiben. Dazu fügen wir dem Element, das die Chatnachrichten enthält, overscroll-behavior: contain hinzu:

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

Im Wesentlichen erstellen wir eine logische Trennung zwischen dem Scrollkontext des Chatfelds und der Hauptseite. Das Endergebnis ist, dass die Hauptseite angezeigt wird, wenn der Nutzer den Anfang/das Ende des Chat-Verlaufs erreicht. Scrollvorgänge, die in der Chatbox beginnen, werden nicht weitergegeben.

Das Seiten-Overlay-Szenario

Eine weitere Variante des „Unterscroll“-Szenarios besteht darin, dass Inhalte hinter einem Overlay mit fester Position scrollen. Das Werbegeschenk overscroll-behavior ist tot! Der Browser ist hilfsbereit, aber am Ende sieht die Website fehlerhaft aus.

Beispiel – modales Fenster mit und ohne overscroll-behavior: contain:

Vorher: Der Seiteninhalt wird unter dem Overlay gescrollt.
Nach: Der Seiteninhalt scrollt nicht unter dem Overlay.

"Zum Aktualisieren ziehen" deaktivieren

Zum Deaktivieren der Aktion „Zum Aktualisieren ziehen“ wird eine einzelne CSS-Zeile benötigt. Verhindert aber eine Verkettung des Scrollens für das gesamte Element, das den Darstellungsbereich definiert. In den meisten Fällen ist das <html> oder <body>:

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

Durch diese einfache Ergänzung korrigieren wir die doppelten Pull-to-Refresh-Animationen in der Chatbox-Demo und können stattdessen einen benutzerdefinierten Effekt implementieren, der eine übersichtlichere Ladeanimation verwendet. Wenn der Posteingang aktualisiert wird, wird auch der gesamte Posteingang unkenntlich gemacht:

Vorher
Nachher

Hier ist ein Snippet des vollständigen Codes:

<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-Leuchten und Gummibanding-Effekte deaktivieren

Verwende overscroll-behavior-y: none, um den Bounce-Effekt beim Erreichen einer Scroll-Grenze zu deaktivieren:

body {
  /* Disables pull-to-refresh and overscroll glow effect.
     Still keeps swipe navigations. */
  overscroll-behavior-y: none;
}
Vorher: Wenn du die Scroll-Grenze erreichst, wird ein Leuchten angezeigt.
Nachher: Leuchten deaktiviert.

Vollständige Demo

Zusammengenommen erstellt die vollständige Chatbox-Demo mithilfe von overscroll-behavior eine benutzerdefinierte Animation, die zum Aktualisieren nach unten gezogen wird, und verhindert, dass Scrollvorgänge des Chatbox-Widgets nicht maskiert werden. Dies sorgt für eine optimale Nutzererfahrung, die ohne das CSS overscroll-behavior schwierig gewesen wäre.

Demo ansehen | Quelle