Gesteuertes Scrollen mit CSS Scroll Snap

Sie können die Bildlaufsteuerung optimieren, indem Sie Positionen für das Bildlauf-Snapping angeben.

Robert Flack
Robert Flack
Majid Valipour
Majid Valipour

Mit der CSS-Scroll-Snap-Funktion können Webentwickler durch Festlegen von Scroll-Snap-Positionen eine gut steuerbare Scrollfunktion erstellen. Seiten mit Artikeln und Bilderkarussells sind zwei gängige Beispiele dafür. CSS Scroll Snap bietet eine nutzerfreundliche und konsistente API zum Erstellen dieser beliebten UX-Muster.

Hintergrund

Vorteile von Scroll-Snapping

Das Scrollen ist eine beliebte und natürliche Möglichkeit, mit Inhalten im Web zu interagieren. Es ist das native Mittel der Plattform, um Zugriff auf mehr Informationen zu erhalten, als auf dem Bildschirm gleichzeitig sichtbar sind. Dies ist besonders auf mobilen Plattformen mit begrenztem Bildschirmplatz wichtig. Es ist daher keine Überraschung, dass Webautoren Inhalte zunehmend in scrollbaren flachen Listen anstelle von tiefen Hierarchien organisieren.

Der Hauptnachteil des Scrollens ist die mangelnde Präzision. Selten ist ein Scrollen am Ende auf einen Absatz oder Satz ausgerichtet. Das ist noch ausgeprägter bei paginaten oder aufgelisteten Inhalten mit sinnvollen Grenzen, wenn das Scrollen in der Mitte der Seite oder des Bildes endet und es teilweise sichtbar bleibt. Bei diesen Anwendungsfällen ist ein gut steuerbares Scrollen von Vorteil.

Webentwickler haben lange Zeit auf JavaScript-basierte Lösungen zur Steuerung des Scrollens zurückgegriffen, um dieses Problem zu beheben. JavaScript-basierte Lösungen bieten jedoch keine Lösung mit voller Wiedergabetreue, da es keine Primitives zur Scrollanpassung oder keinen Zugriff auf zusammengesetztes Scrollen gibt. CSS Scroll Snap sorgt für eine schnelle, fehlerfreie und nutzerfreundliche Lösung, die in allen Browsern einheitlich funktioniert.

Mit CSS Scroll Snap können Webentwickler jeden Scrollcontainer mit Grenzen für Scrollvorgänge markieren, an denen sie beendet werden sollen. Browser wählen dann je nach Details des Scrollvorgangs, Layout und Sichtbarkeit des Scrollcontainers sowie Details der Snap-Positionen die am besten geeignete Endposition aus und animieren dann reibungslos dorthin. In unserem Beispiel oben wird das sichtbare Bild an seinem Platz fixiert, sobald der Nutzer das Karussell durchgescrollt hat. Es sind keine Scrollanpassungen durch JavaScript erforderlich.

Beispiel für die Verwendung von CSS-Scroll-Snap mit einem Bildkarussell.
Beispiel für die Verwendung von CSS-Scroll-Snap mit einem Bildkarussell. Hier sorgt das Bildlauf-Snapping dafür, dass das Bild am Ende des Scrollens horizontal mittig im Scrollcontainer ausgerichtet ist.

CSS-Scroll-Snap

Beim Scroll-Snapping wird der Scroll-Offset eines Scroll-Containers so angepasst, dass er sich nach Abschluss des Scrollvorgangs an einer bevorzugten Snap-Position befindet.

Mit der Property scroll-snap-type kann für einen Scrollcontainer das Scroll-Snapping aktiviert werden. Dies bedeutet, dass der Browser diesen Scrollcontainer an den von seinen untergeordneten Elementen generierten Anlegepositionen anpeilen soll. scroll-snap-type bestimmt die Achse, entlang der gescrollt wird: x, y oder both, und die Stringenz des Anpassens: mandatory, proximity. Mehr dazu später.

Eine Anlegeposition kann durch Deklarieren einer gewünschten Ausrichtung für ein Element erstellt werden. Diese Position ist der Scroll-Offset, bei dem der nächstgelegene übergeordnete Scroll-Container und das Element wie für die jeweilige Achse angegeben ausgerichtet sind. Für jede Achse sind die folgenden Ausrichtungen möglich: start, end, center.

Bei einer start-Ausrichtung sollte der Startrand des Snap-Ports des Scrollcontainers mit dem Startrand des Snap-Bereichs des Elements übereinstimmen. Bei den Ausrichtungen end und center bedeutet das, dass der Endrand oder die Mitte des Snap-Supports des Scrollcontainers mit dem Endrand oder der Mitte des Snap-Bereichs des Elements übereinstimmen sollte.

Beispiel für verschiedene Ausrichtungen auf der horizontalen Scrollachse.

Die folgenden Beispiele veranschaulichen die Verwendung dieser Konzepte.

Ein häufiger Anwendungsfall für Scroll-Snapping ist ein Bilderkarussell. Wenn Sie beispielsweise ein horizontales Bilderkarussell erstellen möchten, das beim Scrollen auf jedes Bild springt, können Sie für den Scrollcontainer ein obligatorisches scroll-snap-type auf der horizontalen Achse angeben. Legen Sie für jedes Bild scroll-snap-align: center fest, damit das Bild beim Anspringen im Karussell zentriert wird.

#gallery {
  scroll-snap-type: x mandatory;
  overflow-x: scroll;
  display: flex;
}

#gallery img {
   scroll-snap-align: center;
}
<div id="gallery">
  <img src="cat.jpg">
  <img src="dog.jpg">
  <img src="another_cute_animal.jpg">
</div>

Da die Anlegepositionen mit einem Element verknüpft sind, kann der Anlegealgorithmus intelligent festlegen, wann und wie er anhand des Elements und der Größe des Scrollcontainers anlegt. Angenommen, ein Bild ist größer als das Karussell. Ein naiver Snap-Algorithmus kann verhindern, dass der Nutzer das Bild schwenken kann, um es vollständig zu sehen. Gemäß der Spezifikation müssen Implementierungen diesen Fall jedoch erkennen und es dem Nutzer ermöglichen, frei innerhalb des Bildes zu scrollen und nur an den Rändern anzuspringen.

Demo ansehen | Quellcode

Beispiel: Produktseite mit Kaufprozess

Ein weiterer häufiger Anwendungsfall für Scroll-Snapping sind Seiten mit mehreren logischen Abschnitten, die vertikal durchgescrollt werden können, z. B. eine typische Produktseite. scroll-snap-type: y proximity; ist für solche Fälle besser geeignet. Es stört nicht, wenn ein Nutzer in die Mitte eines bestimmten Bereichs scrollt, aber auch, wenn er sich einem neuen Bereich nähert, wird er darauf aufmerksam gemacht.

So gehts:

article {
  scroll-snap-type: y proximity;
  /* Reserve space for header plus some extra space for sneak peeking. */
  scroll-padding-top: 15vh;
  overflow-y: scroll;
}
section {
  /* Snap align start. */
  scroll-snap-align: start;
}
header {
  position: fixed;
  height: 10vh;
}
<article>
  <header> Header </header>
  <section> Section One </section>
  <section> Section Two </section>
  <section> Section Three </section>
</article>

Scroll-Abstand und -Rahmen

Die Produktseite hat eine feste Kopfzeile oben. Außerdem sollte ein Teil des oberen Bereichs sichtbar bleiben, wenn der Scrollcontainer angedockt ist, um Nutzern einen Designhinweis auf die Inhalte darüber zu geben.

Die Eigenschaft scroll-padding ist eine neue CSS-Eigenschaft, mit der sich der effektive sichtbare Bereich des Scrollcontainers oder Snapports anpassen lässt. Dieser wird bei der Berechnung von Scroll-Snap-Ausrichtungen verwendet. Mit dieser Eigenschaft wird ein Einzug zum Rändern des Padding-Containers des Scrollcontainers definiert. In unserem Beispiel wurde oben ein zusätzlicher Einzug 15vh hinzugefügt, der den Browser anweist, eine niedrigere Position, 15vh unterhalb des oberen Randes des Scrollcontainers, als vertikalen Startrand für das Scroll-Snapping zu verwenden. Beim Anpinnen wird die Startkante des Anpinselelements an diese neue Position ausgerichtet, sodass oben Platz bleibt.

Mit der Eigenschaft scroll-margin wird der Abstand festgelegt, der zum Anpassen des effektiven Snap-Zielfelds verwendet wird. Das funktioniert ähnlich wie scroll-padding für den Snap-Scrollcontainer.

Möglicherweise ist Ihnen aufgefallen, dass diese beiden Properties nicht das Wort „snap“ enthalten. Das ist beabsichtigt, da sie den Bereich für alle relevanten Scrollvorgänge ändern und nicht nur das Scrollen an bestimmte Positionen anpassen. In Chrome werden sie beispielsweise bei der Berechnung der Seitengröße für Scrollvorgänge wie „PageDown“ und „PageUp“ sowie bei der Berechnung des Scrollvorgangs für den Befehl Element.scrollIntoView() berücksichtigt.

Demo ansehen | Quellcode

Interaktion mit anderen Scroll-APIs

DOM Scrolling API

Das Scroll-Snapping erfolgt nach allen Scrollvorgängen, einschließlich derjenigen, die durch ein Script initiiert wurden. Wenn Sie APIs wie Element.scrollTo verwenden, berechnet der Browser die gewünschte Scrollposition des Vorgangs und wendet dann die entsprechende Anpasslogik an, um den endgültigen angepassten Standort zu ermitteln. Daher müssen im Nutzerscript keine manuellen Berechnungen für das Anpinnen durchgeführt werden.

Reibungsloses Scrollen

Mit dem flüssigen Scrollen wird das Verhalten eines programmatischen Scrollvorgangs gesteuert, während das Scroll-Snapping das Ziel bestimmt. Da sie orthogonale Aspekte des Scrollens steuern, können sie zusammen verwendet und sich ergänzen.

Overscroll-Verhalten

Die Overscroll Behavior API steuert, wie das Scrollen über mehrere Elemente hinweg verkettet wird. Sie ist nicht vom Scroll-Snap betroffen.

Einschränkungen und Best Practices

Verwenden Sie keine obligatorische Angleichung, wenn sich die Zielelemente weit voneinander entfernt befinden. Das kann dazu führen, dass Inhalte zwischen den Anlegepunkten nicht mehr zugänglich sind.

In vielen Fällen kann Scroll-Snapping als Verbesserung hinzugefügt werden, ohne dass die Funktion erkannt werden muss. Verwenden Sie bei Bedarf @supports oder CSS.supports, um die Unterstützung für CSS Scroll Snap zu erkennen. Verwenden Sie scroll-snap-type nicht, da dieses Zeichen auch in der eingestellten Spezifikation enthalten ist.

Funktionserkennung in CSS

@supports (scroll-snap-align: start) {
  article {
    scroll-snap-type: y proximity;
    scroll-padding-top: 15vh;
    overflow-y: scroll;
  }
}

Feature-Erkennung in JavaScript

if (CSS.supports('scroll-snap-align: start')) {
  // use css scroll snap
} else {
  // use fallback
}

Gehen Sie nicht davon aus, dass APIs zum programmatischen Scrollen wie Element.scrollTo immer am angeforderten Scroll-Offset enden. Durch das Scroll-Snapping wird der Scroll-Offset möglicherweise angepasst, nachdem das programmatische Scrollen abgeschlossen ist. Diese Annahme war schon vor der Einführung von Scroll-Snapping nicht sinnvoll, da das Scrollen aus anderen Gründen unterbrochen werden kann. Das gilt aber vor allem für Scroll-Snapping.

Zukünftige Arbeit

Das Scrollen stand im Mittelpunkt einer aktuellen Umfrage des Chrome-Teams. Die Umfrageergebnisse haben mehrere Bereiche aufgezeigt, in denen zusätzliche Arbeit erforderlich ist, um die Lücke zwischen Plug-in-Bibliotheken und CSS zu schließen. Die anstehenden Aufgaben konzentrieren sich auf scroll-snap, einschließlich:

  1. API-Verfügbarkeit und ‑Kompatibilität für alle Browser
  2. Arbeiten Sie an neuen CSS APIs wie scroll-start.
  3. Mit neuen JS-Ereignissen wie snapChanged() arbeiten.