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

Kurzfassung

Mit der CSS-Property overscroll-behavior können Entwickler das standardmäßige Scrollverhalten des Browsers überschreiben, wenn das Ende des Inhalts erreicht wird. Anwendungsfälle sind beispielsweise das Deaktivieren der Funktion „Zum Aktualisieren wischen“ auf Mobilgeräten, das Entfernen von Überscroll-Glühen und Gummibandeffekten sowie das Verhindern des Scrollens von Seiteninhalten, wenn sie sich unter einem Modal- oder Overlay befinden.

Hintergrund

Scrollgrenzen und Scroll-Verkettung

Scroll-Ketten in Chrome für 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. Ein Beispiel wäre ein App-Bereich mit einer großen Anzahl von Elementen, durch die der Nutzer 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 „Scrollgrenze“. Sehen Sie sich aber an, was passiert, wenn der Nutzer weiter scrollt. Die Inhalte hinter der Leiste werden gescrollt. Das Scrollen wird vom übergeordneten Container übernommen, im Beispiel also von der Hauptseite selbst.

Dieses Verhalten wird als Scroll-Kettenreaktion bezeichnet und ist das Standardverhalten des Browsers beim Scrollen von Inhalten. Oft ist die Standardeinstellung ziemlich gut, aber manchmal ist sie nicht wünschenswert oder sogar unerwartet. Bei bestimmten Apps kann es sinnvoll sein, das Nutzererlebnis zu ändern, wenn der Nutzer eine Scrollgrenze erreicht.

Der Effekt des Wischens zum Aktualisieren

„Zum Aktualisieren wischen“ ist eine intuitive Geste, die durch mobile Apps wie Facebook und Twitter populär wurde. 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 Pull-to-Refresh-Funktion von Twitter
zum Aktualisieren eines Feeds in der PWA.
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 die Seite versehentlich aktualisiert. Es kann auch sein, dass eine doppelte Aktualisierungsanimation angezeigt wird. Alternativ kann die Browseraktion angepasst werden, um sie besser an das Branding der Website anzupassen. Leider ist diese Art der Anpassung schwierig umzusetzen. Entwickler schreiben unnötiges JavaScript, fügen nicht passive Touch-Listener hinzu (die das Scrollen blockieren) oder stecken die gesamte Seite in ein 100vw/vh-<div> (um ein Überlaufen der Seite zu verhindern). Diese Problemumgehungen 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 damit unter anderem die Scroll-Kettenfunktion aufheben, die Aktion „Zum Aktualisieren ziehen“ deaktivieren/anpassen und Gummibandeffekte auf iOS-Geräten deaktivieren (wenn Safari overscroll-behavior implementiert). Das Beste daran ist, dass die Verwendung von overscroll-behavior die Seitenleistung nicht beeinträchtigt, wie in der Einführung beschrieben.

Das Attribut kann drei Werte annehmen:

  1. auto: Standardeinstellung. Scrollen, das am Element beginnt, kann auf übergeordnete Elemente übertragen werden.
  2. contain: Verhindert das Verketten von Scrollvorgängen. Scrollen wird nicht auf übergeordnete Elemente übertragen, aber lokale Effekte innerhalb des Knotens werden angezeigt. Dazu gehören beispielsweise der Overscroll-Glüheffekt unter Android oder der Gummibandeffekt unter iOS, der Nutzer darüber informiert, dass sie eine Scrollgrenze erreicht haben. Hinweis: Wenn Sie overscroll-behavior: contain für das Element html verwenden, werden Navigationsaktionen durch Überscrollen 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 einige Beispiele an, um zu sehen, wie overscroll-behavior verwendet wird.

Verhindern, dass ein Element mit fester Position beim Scrollen verlassen wird

Das Chatbox-Szenario

Der Inhalt unter dem Chatfenster wird ebenfalls gescrollt :(

Stellen Sie sich ein fix positioniertes Chatfeld vor, das sich unten auf der Seite befindet. Die Absicht ist, 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.

Bei dieser App ist es sinnvoller, wenn das Scrollen innerhalb des Chatfelds bleibt. 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 Grunde schaffen wir eine logische Trennung zwischen dem Scrollkontext des Chatfelds und der Hauptseite. Das Endergebnis ist, dass die Hauptseite an Ort und Stelle bleibt, wenn der Nutzer den Anfang oder das Ende des Chatverlaufs erreicht. Scrollbewegungen, die im Chatfenster beginnen, werden nicht weitergegeben.

Das Szenario für Seiten-Overlays

Eine weitere Variante des „Underscroll“-Szenarios ist, wenn Inhalte hinter einem Overlay mit fester Position scrollen. Du erhältst ein tolles Geschenkoverscroll-behavior! Der Browser versucht zwar, hilfreich zu sein, 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.
Nachher: Der Seiteninhalt wird nicht unter das Overlay gescrollt.

"Zum Aktualisieren ziehen" deaktivieren

Die Aktion „Zum Aktualisieren wischen“ lässt sich mit einer einzigen CSS-Zeile deaktivieren. Verhindern Sie einfach die Scroll-Kette für das gesamte Element, das den Viewport 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;
}

Mit dieser einfachen Ergänzung können wir die doppelten Pull-to-Refresh-Animationen in der Chatbox-Demo korrigieren und stattdessen einen benutzerdefinierten Effekt mit einer ansprechenderen Ladeanimation implementieren. Der gesamte Posteingang wird beim Aktualisieren ebenfalls unkenntlich gemacht:

Vorher
Nachher

Hier ist ein Ausschnitt aus dem vollständigen 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>

Glühen und Gummibandeffekt beim Überscrollen deaktivieren

Verwenden Sie overscroll-behavior-y: none, um den Sprungeffekt beim Erreichen eines Scrollbereichs zu deaktivieren:

body {
  /* Disables pull-to-refresh and overscroll glow effect.
     Still keeps swipe navigations. */
  overscroll-behavior-y: none;
}
Vorher: Wenn das Ende des Scrollbereichs erreicht wird, wird ein Glühen angezeigt.
Nachher: Glühen deaktiviert.

Vollständige Demo

In der vollständigen Chatbox-Demo wird overscroll-behavior verwendet, um eine benutzerdefinierte Animation zum Aktualisieren durch Ziehen zu erstellen und zu verhindern, dass beim Scrollen das Chatbox-Widget verlassen wird. Das sorgt für eine optimale Nutzererfahrung, die ohne CSSoverscroll-behavior schwierig zu erreichen gewesen wäre.

Demo ansehen | Quellcode