CSS Scroll Snapping ermöglicht es Ihnen, den Viewport nach Abschluss des Scrollens an bestimmten Elementen oder Positionen zu sperren. Es eignet sich hervorragend zum Erstellen von Interaktionen wie dieser

Browserunterstützung und grundlegende Verwendung
Die Browserunterstützung für CSS Scroll Snapping hat sich seit der Einführung im Jahr 2016 erheblich verbessert. Google Chrome (69+), Firefox, Edge und Safari unterstützen alle eine Version davon.
Diese Daten zur Browserunterstützung stammen von Caniuse, das weitere Details enthält. Eine Zahl gibt an, dass der Browser die Funktion ab dieser Version unterstützt.
Desktop
| Chrome | Firefox | IE | Edge | Safari |
|---|---|---|---|---|
| 69 | 68 | 11* | 79 | 11 |
Mobil / Tablet
| Android Chrome | Android Firefox | Android | iOS Safari |
|---|---|---|---|
| 127 | 127 | 127 | 11.0-11.2 |
Scroll Snapping wird verwendet, indem die Eigenschaft scroll-snap-type auf einem Container-Element und die Eigenschaft scroll-snap-align auf Elementen darin gesetzt werden. Wenn das Container-Element gescrollt wird, rastet es an den von Ihnen definierten Kindelementen ein. In seiner einfachsten Form sieht es so aus
<div class="container">
<section class="child"></section>
<section class="child"></section>
<section class="child"></section>
<p>...</p>
</div>
.container {
scroll-snap-type: y mandatory;
}
.child {
scroll-snap-align: start;
}
Dies unterscheidet sich von der ersten Version der Spezifikation, die es Ihnen erlaubte, Snap-Punkte manuell mit dem Schlüsselwort repeat festzulegen.
.container {
/* OLD */
scroll-snap-points-y: repeat(300px);
}
Diese Methode ist ziemlich begrenzt. Da sie nur gleichmäßig verteilte Snap-Punkte zulässt, können Sie keine Benutzeroberfläche erstellen, die an unterschiedlich große Elemente einrastet. Wenn sich die Form von Elementen über verschiedene Bildschirmgrößen hinweg ändert, werden Sie ebenfalls auf Probleme stoßen.
Zum Zeitpunkt des Schreibens unterstützen Firefox, Internet Explorer und Edge die ältere Version der Spezifikation, während Chrome (69+) und Safari die neuere, elementbasierte Methode unterstützen.
Sie können beide Methoden nebeneinander verwenden (wenn Ihr Layout dies zulässt), um beide Browsergruppen zu unterstützen.
.container {
scroll-snap-type: mandatory;
scroll-snap-points-y: repeat(300px);
scroll-snap-type: y mandatory;
}
.child {
scroll-snap-align: start;
}
Ich würde argumentieren, dass eine flexiblere Option darin besteht, die elementbasierte Syntax ausschließlich zu verwenden und ein Polyfill zu laden, um Browser zu unterstützen, die sie noch nicht unterstützen. Dies ist die Methode, die ich in den folgenden Beispielen verwende.
Leider enthält das Polyfill keinen Browser-Bundle, sodass die Verwendung etwas knifflig ist, wenn Sie keinen Build-Prozess verwenden. Der einfachste Weg, dies zu umgehen, den ich gefunden habe, ist, das Skript auf bundle.run zu verlinken und es mit cssScrollSnapPolyfill() zu initialisieren, sobald der DOM geladen ist. Es ist auch erwähnenswert, dass dieses Polyfill nur die elementbasierte Syntax unterstützt, nicht die repeat-Methode.
Eigenschaften des übergeordneten Containers
Wie bei jeder Eigenschaft ist es ratsam, sich mit den akzeptierten Werten vertraut zu machen. Scroll-Snap-Eigenschaften werden sowohl auf übergeordnete als auch auf untergeordnete Elemente angewendet, mit spezifischen Werten für jedes. Ähnlich wie bei Flexbox und Grid, wo das übergeordnete Element zu einem "Flex"- oder "Grid"-Container wird. In diesem Fall wird das übergeordnete Element sozusagen zu einem Snap-Container.
Hier sind die Eigenschaften und Werte für den übergeordneten Container und wie sie funktionieren.
scroll-snap-type „mandatory“ vs. „proximity“
Der Wert mandatory bedeutet, dass der Browser unbedingt zu einem Snap-Punkt einrasten muss, wenn der Benutzer das Scrollen beendet. Die Eigenschaft proximity ist weniger streng – sie bedeutet, dass der Browser möglicherweise zu einem Snap-Punkt einrastet, wenn dies angemessen erscheint. Nach meiner Erfahrung tritt dies ein, wenn Sie das Scrollen innerhalb weniger hundert Pixel eines Snap-Punkts beenden.
In meiner eigenen Arbeit habe ich festgestellt, dass mandatory zu einer konsistenteren Benutzererfahrung führt, aber es kann auch gefährlich sein, wie die Spezifikation darauf hinweist. Stellen Sie sich ein Szenario vor, in dem ein Element innerhalb eines scrollenden Containers höher ist als der Viewport.

Wenn dieser Container auf scroll-snap-type: mandatory eingestellt ist, rastet er immer entweder am oberen Rand des Elements oder am oberen Rand des darunter liegenden Elements ein, wodurch der mittlere Teil des hohen Elements unmöglich zu erreichen ist.
scroll-padding
Standardmäßig rastet der Inhalt an den Rändern des Containers ein. Sie können dies ändern, indem Sie die Eigenschaft scroll-padding auf dem Container setzen. Sie folgt der gleichen Syntax wie die normale padding-Eigenschaft.
Dies kann nützlich sein, wenn Ihr Layout Elemente enthält, die den Inhalt stören könnten, z. B. eine feste Kopfzeile.
Eigenschaften für die Kindelemente
Nun kommen wir zu den Eigenschaften für Kindelemente.
scroll-snap-align
Damit können Sie festlegen, welcher Teil des Elements am Container einrasten soll. Es hat drei mögliche Werte: start, center und end.

Diese beziehen sich auf die Scroll-Richtung. Wenn Sie vertikal scrollen, bezieht sich start auf den oberen Rand des Elements. Wenn Sie horizontal scrollen, bezieht es sich auf den linken Rand. center und end folgen demselben Prinzip. Sie können für jede Scroll-Richtung einen anderen Wert angeben, getrennt durch ein Leerzeichen.
scroll-snap-stop „normal“ vs. „always“
Standardmäßig greift Scroll Snapping nur, wenn der Benutzer das Scrollen beendet, was bedeutet, dass er mehrere Snap-Punkte überspringen kann, bevor er zum Stillstand kommt.
Sie können dies ändern, indem Sie scroll-snap-stop: always auf einem beliebigen Kindelement festlegen. Dies zwingt den Scroll-Container, bei diesem Element anzuhalten, bevor der Benutzer weiter scrollen kann.
Zum Zeitpunkt des Schreibens unterstützt kein Browser scroll-snap-stop nativ, obwohl es einen Tracking-Bug für Chrome gibt.
Werfen wir einen Blick auf einige Beispiele für Scroll Snap in Aktion.
Beispiel 1: Vertikale Liste
Um eine vertikale Liste bei jedem Listenelement einrasten zu lassen, sind nur ein paar Zeilen CSS erforderlich. Zuerst weisen wir den Container an, entlang seiner vertikalen Achse einzurasten
.container {
scroll-snap-type: y mandatory;
}
Dann definieren wir die Snap-Punkte. Hier geben wir an, dass die Oberkante jedes Listenelements ein Snap-Punkt sein wird.
.child {
scroll-snap-align: start;
}
Beispiel 2: Horizontaler Schieberegler
Um einen horizontalen Schieberegler zu erstellen, weisen wir den Container an, entlang seiner x-Achse einzurasten. Wir verwenden auch scroll-padding, um sicherzustellen, dass die Kindelemente in der Mitte des Containers einrasten.
.container {
scroll-snap-type: x mandatory;
scroll-padding: 50%;
}
Dann geben wir dem Container an, an welchen Punkten er einrasten soll. Um die Galerie zu zentrieren, definieren wir den Mittelpunkt jedes Elements als Snap-Punkt.
.child {
scroll-snap-align: center;
}
Beispiel 3: Vertikaler Vollbildmodus
Wir können die Snap-Punkte direkt am Element festlegen.
html { /* body won't work ¯\_(ツ)_/¯ */
scroll-snap-type: y mandatory;
}
/* Although I'm told that html doesn't work in Safari
and body does, so maybe use both? */
Dann machen wir jeden Abschnitt so groß wie der Viewport und definieren die Oberkante als Snap-Punkt.
section {
height: 100vh;
width: 100vw;
scroll-snap-align: start;
}
Beispiel 4: Horizontaler Vollbildmodus
Dies ist im Grunde dasselbe Konzept wie bei der vertikalen Version, nur mit dem Snap-Punkt auf der x-Achse.
body {
scroll-snap-type: x mandatory;
}
section {
height: 100vh;
width: 100vw;
scroll-snap-align: start;
}
Beispiel 5: 2D-Bildraster
Scroll Snapping kann in zwei Richtungen gleichzeitig funktionieren. Auch hier können wir scroll-snap-type direkt am Element festlegen.
.container {
scroll-snap-type: both mandatory;
}
Dann definieren wir die obere linke Ecke jeder Kachel als Snap-Punkt.
.tile {
scroll-snap-align: start;
}
Einige Gedanken zur Benutzererfahrung
Das Scrollen zu manipulieren ist ein riskantes Geschäft. Da es ein grundlegender Teil der Interaktion mit dem Web ist, kann jede Änderung daran beunruhigend wirken – der Begriff Scrolljacking wurde früher verwendet, um diese Art von Erlebnis zu beschreiben.
Das Großartige an CSS-basiertem Scroll Snapping ist, dass Sie die Kontrolle über die Scroll-Position nicht direkt übernehmen. Stattdessen geben Sie dem Browser lediglich eine Liste von Positionen, zu denen er auf eine für die Plattform, die Eingabemethode und die Benutzereinstellungen geeignete Weise einrasten soll. Das bedeutet, dass eine von Ihnen erstellte Scroll-Oberfläche genauso gut wie die native Oberfläche (d. h. mit den gleichen Animationen usw.) auf jeder Plattform, auf der sie angezeigt wird, funktioniert.
Für mich ist das der entscheidende Vorteil von CSS Scroll Snapping gegenüber JavaScript-Bibliotheken, die ähnliche Funktionalität bieten.
Das funktioniert meiner Erfahrung nach ziemlich gut, besonders auf Mobilgeräten. Vielleicht liegt das daran, dass Scroll Snapping bereits Teil der nativen Benutzeroberfläche auf mobilen Plattformen ist. (Stellen Sie sich die Startbildschirme unter iOS und Android vor – sie sind im Wesentlichen horizontale Schieberegler mit Snap-Punkten.) Die Interaktion unter Chrome auf Android ist besonders gut, da sie sich wie normales Scrollen anfühlt, aber der Viewport immer zufällig an einem Snap-Punkt zum Stillstand kommt.
Es gibt sicherlich einige ausgeklügelte Berechnungen, die dafür sorgen. Dank CSS Scroll Snapping erhalten wir dies kostenlos.
Natürlich sollten wir nicht damit anfangen, überall Snap-Punkte einzufügen. Dinge wie Artikelseiten kommen auch ohne gut zurecht. Aber ich denke, sie können in der richtigen Situation eine schöne Ergänzung sein – Bildgalerien, Diashows scheinen gute Kandidaten zu sein, aber vielleicht gibt es darüber hinaus Potenzial.
Fazit
Wenn Scroll Snapping durchdacht eingesetzt wird, kann es ein nützliches Gestaltungswerkzeug sein. CSS Snap-Punkte ermöglichen es Ihnen, sich in die native Scroll-Interaktion des Browsers einzuhängen, sodass Ihre Benutzeroberfläche nahtlos und reibungslos wirkt. Mit einer JavaScript-API, die möglicherweise am Horizont erscheint, werden diese noch leistungsfähiger werden. Dennoch ist eine leichte Hand wahrscheinlich der beste Ansatz.
Die Benutzererfahrung auf Mobilgeräten ist immer noch ziemlich schlecht. Beim Ausprobieren der Demos oben gab es viele unerwartete Verhaltensweisen, wie z. B. dass einige Elemente nicht überscrollt werden konnten und zu scheinbar willkürlichen Punkten gesprungen wurde. Wo es funktioniert, ist es irgendwie nett.
Demos funktionieren nicht im Safari iOS 11.3.
WebKit-Präfixe sollten das beheben.
@Brant Das tun sie nicht. Safari 11 sollte es ohne Präfixe unterstützen. Ältere Versionen verwendeten Präfixe.
Es scheint, dass Safari Scroll Snap nur scheinbar unterstützt, es aber eigentlich nicht tut. Ich konnte die Demos wirklich nicht zum Laufen bringen, konnte nicht einmal eine Demo ohne Polyfill zum Laufen bringen.
Kein Problem in Chrome oder Desktop Safari.
Das funktioniert auch in Opera seit einigen Versionen :-)
Danke für diesen Artikel. Da die Unterstützung endlich nach Chrome kommt, ist es möglich, dass wir das jetzt nutzen können.
Ich hatte gehofft, dass jemand einen Blogbeitrag darüber schreibt, wie man X-Browser-Scroll-Snap-Unterstützung erreicht, und jetzt gibt es ihn.
Es mag sich auf einem Mobilgerät anders anfühlen, aber als ich die Demos auf meinem Laptop ausprobiert habe, wurde ich wirklich wütend. Es fühlt sich überhaupt nicht natürlich an und ich hatte Schwierigkeiten, zu dem gewünschten Punkt zu navigieren. Wenn ich eine solche Erfahrung auf einer Live-Website hätte, würde ich diese Website nie wieder besuchen. Daher ist Ihre Warnung dort ziemlich wichtig. Wenn Sie an den Scrollvorgängen der Leute herumfummeln, sollten Sie 100% sicher sein, was Sie tun. Sehr interessanter Artikel aber.
Die Technologie ist sehr interessant und kann bei richtiger Anwendung für den Benutzer nützlich sein.
Aber bisher ist solches Scroll-Jacking ein Albtraum für die Benutzerfreundlichkeit. Sie dürfen anwenden, aber niemals die Kontrolle des Benutzers entziehen.
Die Unterstützung ist noch nicht gut genug. Ihr Bild zeigt die Unterstützung von Chrome 69, aber im August 2018 hat Version 69 nur eine Nutzung von 0,04 %. Chrome 67 hat weltweit eine Nutzung von 23 %, aber keine Scroll-Snap-Unterstützung.
Ich habe mit Beispiel 4: Horizontal Full Screen auf Codepen in Firefox 60.2.0esr gespielt und es funktioniert hervorragend, aber wenn ich den gesamten Code in eine HTML-Datei einfüge, funktioniert er nicht mehr. Was brauche ich noch?