Elastisches Overflow-Scrolling

Avatar of Dave Seidman
Dave Seidman am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Ein Kunde fragte, ob wir das „Gummiband“-Scrollverhalten vieler mobiler Geräte imitieren könnten. Ich bin sicher, Sie wissen, wovon ich spreche. Es ist ein Verhalten, das bereits existiert und in den meisten Browsern automatisch passiert. In iOS Safari zum Beispiel ist es möglich, ein paar hundert Pixel über den oberen oder unteren Rand des Viewports hinaus zu scrollen; beim Loslassen schnappt die Seite wieder an ihre Position zurück.

Ich hatte von einigen Fällen gehört, in denen jemand diesen Bounce-Effekt verhindern wollte, aber bisher hatte mich niemand gebeten, ihn aktiv zu implementieren – insbesondere so, dass er auch Geräte ohne Touch-Interface unterstützt. Ich war tatsächlich ein wenig überrascht, dass es dafür keine existierende CSS-Eigenschaft gibt. Es gibt zwar die nicht-standardisierte Eigenschaft -webkit-overflow-scrolling, aber die ist für eine andere Art von „Momentum“-Scrolling gedacht. Zudem möchte ich mich nicht auf eine nicht-standardisierte Eigenschaft verlassen, die nicht auf dem Weg ist, Teil der Spezifikationen zu werden.

OK, was also, wenn wir diese Art von Rubber-Banding in unserer Arbeit erzwingen wollen? Zunächst bräuchten wir eine Art Element, das als Container für den Inhalt fungiert, der gescrollt werden soll. Von dort aus könnten wir natürlich zu JavaScript greifen, aber das bedeutet, Scroll-Listener oder eine Kombination aus pointerDown, pointerUp und pointerMove Events hinzuzufügen, ganz zu schweigen von der Verfolgung von Positionen, Trägheitsbewegungen usw.

Eine reine CSS-Lösung wäre weitaus idealer.

Hier ist ein Container mit ein paar Kind-Elementen

<div class="carousel">
  <div class="slides">
    <div class="slide">1</div>
    <div class="slide">2</div>
    <div class="slide">3</div>
    <div class="slide">4</div>
    <div class="slide">5</div>
  </div>
</div>

Lassen Sie uns zunächst einige Basis-Styles festlegen, um eine Situation zu schaffen, in der wir garantiert über einen Eltern-Container hinauslaufen (Overflow).

/* Parent container with fixed dimensions for overflow */
.carousel {
  width: 200px;
  height: 400px;
  overflow-x: hidden;
  overflow-y: auto;
}

/* Wrapper for slides, stacked in a column */
.slides {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  width: 100%;
  height: fit-content;
}

/* Each slide is the full width of the carousel */
.slide {
  width: 100%;
  aspect-ratio: 1;
}

Beginnen wir damit, vertikale Abstände (Margins) hinzuzufügen. Wenn Ihr Container nur ein langes Element enthält, fügen Sie den Abstand oben und unten am Kind-Element hinzu. Wenn der Container mehrere Kinder hat, sollten Sie margin oben am ersten Kind-Element und unten am letzten Kind-Element hinzufügen.

.carousel > .slides > .slide:first-child {
  margin-top: 100px;
}

.carousel > .slides > .slide:last-child {
  margin-bottom: 100px;
}

Großartig! Wir können jetzt über die Ränder hinaus scrollen, aber wir brauchen etwas, das alles wieder zurückschnappen lässt, nachdem der Benutzer den Finger oder Zeiger hebt. Hierfür benötigen wir die Eigenschaften scroll-snap-type und scroll-snap-align.

.carousel {
  scroll-snap-type: y mandatory;
}

.carousel > .slides > .slide {
  scroll-snap-align: start;
}

.carousel > .slides > .slide:first-child {
  margin-top: 100px;
}

.carousel > .slides > .slide:last-child {
  scroll-snap-align: end;
  margin-bottom: 100px;
}

Beachten Sie, dass das Gleiche auch für ein horizontal scrollendes Element gilt. Dafür müssten Sie die Dinge so anpassen, dass margin an den linken und rechten Rändern des Elements angewendet wird, anstatt an den oberen und unteren. Außerdem sollten Sie den Wert der Eigenschaft scroll-snap-type von y mandatory auf x mandatory ändern, wenn Sie schon dabei sind.

Das ist eigentlich schon alles! Hier ist die finale Demo

Ich weiß, ich weiß. Das ist kein weltbewegender oder bahnbrechender Effekt, aber er löst eine sehr spezifische Situation. Und falls Sie sich einmal in dieser Situation befinden, haben Sie nun etwas in der Hinterhand, das Sie verwenden können.

Zusätzliche Ressourcen