Komponente „Stories“ erstellen

Eine grundlegende Übersicht darüber, wie Sie im Web eine ähnliche Funktion wie Instagram Stories erstellen können.

In diesem Beitrag möchte ich meine Überlegungen zum Erstellen einer Stories-Komponente für das Web teilen, die responsiv ist, die Tastaturnavigation unterstützt und in allen Browsern funktioniert.

Demo

Wenn Sie eine praktische Demonstration zum Erstellen dieser Stories-Komponente bevorzugen, sehen Sie sich das Codelab für die Stories-Komponente an.

Wenn Sie sich lieber ein Video ansehen, finden Sie hier eine YouTube-Version dieses Beitrags:

Übersicht

Zwei beliebte Beispiele für die UX von Stories sind Snapchat Stories und Instagram Stories (und natürlich Fleets). Im Allgemeinen sind Stories ein nur für Mobilgeräte verfügbares, auf Tippen ausgerichtetes Muster für die Navigation durch mehrere Abos. Auf Instagram öffnen Nutzer beispielsweise die Story eines Freundes und sehen sich die Bilder darin an. In der Regel tun sie das mit vielen Freunden gleichzeitig. Wenn der Nutzer auf die rechte Seite des Geräts tippt, springt er zur nächsten Story dieses Freundes. Durch Wischen nach rechts springt ein Nutzer zu einem anderen Freund. Eine Story-Komponente ähnelt einem Karussell, ermöglicht aber die Navigation in einem mehrdimensionalen Array im Gegensatz zu einem eindimensionalen Array. Es ist, als ob sich in jedem Karussell ein weiteres Karussell befindet. 🤯

Visualisiertes mehrdimensionales Array mit Karten. Von links nach rechts ist ein Stapel von Karten mit lila Rahmen zu sehen. Jede Karte enthält eine oder mehrere Karten mit cyanfarbenem Rahmen. Liste in einer Liste.
 1. Karussell mit Freunden
 2. „Gestapeltes“ Karussell mit Stories
👍 Liste in einer Liste, d. h. ein mehrdimensionales Array

Die richtigen Tools für die Aufgabe auswählen

Alles in allem war diese Komponente dank einiger wichtiger Funktionen der Webplattform ziemlich einfach zu erstellen. Sehen wir uns die einzelnen Tabs etwas näher an.

CSS-Raster

Unser Layout war für CSS Grid kein Problem, da es mit einigen leistungsstarken Möglichkeiten zur Verwaltung von Inhalten ausgestattet ist.

Layout „Freunde“

Unser primärer .stories-Komponenten-Wrapper ist eine mobile-first horizontale Scrollansicht:

.stories {
  inline-size: 100vw;
  block-size: 100vh;

  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;

  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}

/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
  max-inline-size: 480px;
  max-block-size: 848px;
}
Mit dem Gerätemodus der Chrome-Entwicklertools die vom Raster erstellten Spalten hervorheben

Sehen wir uns das grid-Layout genauer an:

  • Wir füllen den Darstellungsbereich auf Mobilgeräten explizit mit 100vh und 100vw und beschränken die Größe auf Computern.
  • / trennt die Zeilen- und Spaltenvorlagen.
  • auto-flow wird mit grid-auto-flow: column übersetzt
  • Die Autoflow-Vorlage ist 100%, was in diesem Fall der Breite des Scrollfensters entspricht.

Auf einem Smartphone entspricht die Zeilengröße der Höhe des Darstellungsbereichs und jede Spalte der Breite des Darstellungsbereichs. Im Beispiel mit Snapchat- und Instagram-Storys ist jede Spalte die Story eines Freundes. Die Stories von Freunden sollen außerhalb des Darstellungsbereichs fortgesetzt werden, damit wir dorthin scrollen können. Grid erstellt so viele Spalten, wie für das Layout des HTML-Codes für jede Freundesgeschichte erforderlich sind. Dadurch entsteht ein dynamischer und responsiver Scrollcontainer. Mit Grid konnten wir den gesamten Effekt zentralisieren.

Stapeln

Für jeden Freund benötigen wir die Stories in einem paginierungsbereiten Zustand. Zur Vorbereitung auf die Animation und andere interessante Muster habe ich einen Stack ausgewählt. Mit „Stapel“ meine ich, dass Sie von oben auf ein Sandwich blicken, nicht von der Seite.

Mit dem CSS-Grid können wir ein Raster mit einer einzelnen Zelle (d. h. ein Quadrat) definieren, bei dem die Zeilen und Spalten einen Alias ([story]) haben. Anschließend wird jedes untergeordnete Element diesem Alias-Bereich mit einer einzelnen Zelle zugewiesen:

.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
.story {
  grid-area: story;
  background-size: cover;
  …
}

Dadurch wird die Stapelreihenfolge durch das HTML gesteuert und alle Elemente bleiben im Fluss. Beachten Sie, dass wir nichts mit der absolute-Positionierung oder z-index tun mussten und auch keine Box-Korrektur mit height: 100% oder width: 100% erforderlich war. Das übergeordnete Raster hat bereits die Größe des Ansichtsfensters für das Story-Bild definiert, sodass keine dieser Story-Komponenten angewiesen werden musste, es auszufüllen.

CSS Scroll Snap Points

Mit der Spezifikation für CSS Scroll Snap Points lassen sich Elemente beim Scrollen ganz einfach im Darstellungsbereich fixieren. Bevor es diese CSS-Eigenschaften gab, musste man JavaScript verwenden, was gelinde gesagt kompliziert war. In Introducing CSS Scroll Snap Points von Sarah Drasner finden Sie eine gute Übersicht über die Verwendung.

Horizontales Scrollen ohne und mit scroll-snap-points-Stilen. Ohne diese Funktion können Nutzer wie gewohnt uneingeschränkt scrollen. Damit wird der Browser sanft auf jedem Element platziert.
Übergeordnetes Element
.stories {
  display: grid;
  grid: 1fr / auto-flow 100%;
  gap: 1ch;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior: contain;
  touch-action: pan-x;
}
Übergeordnetes Element mit Overscroll definiert das Einrastverhalten.
Kind
.user {
  display: grid;
  grid: [story] 1fr / [story] 1fr;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
Kinder können sich dafür entscheiden, ein Ziel für das Einrasten zu sein.

Ich habe mich aus mehreren Gründen für Scroll Snap Points entschieden:

  • Kostenlose Barrierefreiheit: In der Spezifikation für Scroll Snap Points ist festgelegt, dass durch Drücken der Tasten Linkspfeil und Rechtspfeil standardmäßig durch die Snap Points navigiert werden soll.
  • Eine wachsende Spezifikation: Die Spezifikation für Scroll Snap Points wird ständig um neue Funktionen und Verbesserungen erweitert. Das bedeutet, dass meine Stories-Komponente von nun an wahrscheinlich nur noch besser wird.
  • Einfache Implementierung: Scroll-Snap-Punkte sind praktisch für den touch-zentrierten horizontalen Paginierungs-Anwendungsfall konzipiert.
  • Ungebundene Trägheit im Plattformstil. Jede Plattform scrollt und stoppt in ihrem eigenen Stil, im Gegensatz zur normalisierten Trägheit, die einen unnatürlichen Scroll- und Stoppstil haben kann.

Browserübergreifende Kompatibilität

Wir haben die Funktion in Opera, Firefox, Safari und Chrome sowie auf Android und iOS getestet. Hier ist eine kurze Übersicht über die Webfunktionen, bei denen wir Unterschiede in Bezug auf die Funktionen und die Unterstützung festgestellt haben.

Einige CSS-Regeln wurden jedoch nicht angewendet, sodass auf einigen Plattformen derzeit keine UX-Optimierungen vorgenommen werden. Ich fand es gut, dass ich diese Funktionen nicht verwalten musste, und bin zuversichtlich, dass sie irgendwann auch in anderen Browsern und auf anderen Plattformen verfügbar sein werden.

scroll-snap-stop

Karussells waren einer der wichtigsten UX-Anwendungsfälle, die zur Erstellung der Spezifikation für CSS Scroll Snap Points geführt haben. Im Gegensatz zu Stories muss ein Karussell nicht immer bei jedem Bild anhalten, nachdem ein Nutzer damit interagiert hat. Es kann in Ordnung oder sogar erwünscht sein, schnell durch das Karussell zu blättern. Stories hingegen werden am besten einzeln durchgegangen. Genau das bietet scroll-snap-stop.

.user {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

Zum Zeitpunkt der Veröffentlichung dieses Beitrags wird scroll-snap-stop nur in Chromium-basierten Browsern unterstützt. Informationen zu Updates finden Sie unter Browserkompatibilität. Es ist jedoch kein Blocker. Es bedeutet nur, dass Nutzer in nicht unterstützten Browsern versehentlich einen Freund überspringen können. Die Nutzer müssen also vorsichtiger sein oder wir müssen JavaScript schreiben, um sicherzustellen, dass ein übersprungener Freund nicht als angesehen markiert wird.

Weitere Informationen finden Sie in der Spezifikation.

overscroll-behavior

Haben Sie schon einmal durch ein modales Fenster gescrollt und plötzlich den Inhalt dahinter gescrollt? overscroll-behavior ermöglicht es dem Entwickler, das Scrollen abzufangen und nicht mehr zuzulassen. Sie eignet sich für alle möglichen Anlässe. Die Komponente „My Stories“ verwendet sie, um zu verhindern, dass zusätzliche Wisch- und Scrollgesten die Komponente verlassen.

.stories {
  overflow-x: auto;
  overscroll-behavior: contain;
}

Safari und Opera waren die beiden Browser, die dies nicht unterstützten, und das ist völlig in Ordnung. Diese Nutzer erhalten ein Overscroll-Erlebnis, wie sie es gewohnt sind, und bemerken diese Verbesserung möglicherweise gar nicht. Ich persönlich bin ein großer Fan davon und verwende es in fast jeder Overscroll-Funktion, die ich implementiere. Es ist eine harmlose Ergänzung, die nur zu einer verbesserten UX führen kann.

scrollIntoView({behavior: 'smooth'})

Wenn ein Nutzer tippt oder klickt und das Ende der Storys eines Freundes erreicht hat, ist es an der Zeit, zum nächsten Freund in der Gruppe der Scroll-Snap-Punkte zu wechseln. Mit JavaScript konnten wir auf den nächsten Freund verweisen und anfordern, dass er in die Ansicht gescrollt wird. Die Unterstützung für die Grundlagen ist großartig. Jeder Browser hat es in die Ansicht gescrollt. Aber nicht jeder Browser hat das 'smooth' getan. Das bedeutet nur, dass sie in die Ansicht gescrollt wird, anstatt einzurasten.

element.scrollIntoView({
  behavior: 'smooth'
})

Safari war der einzige Browser, der behavior: 'smooth' hier nicht unterstützte. Informationen zu Updates finden Sie unter Browserkompatibilität.

Praxisorientiert

Jetzt, da du weißt, wie ich es gemacht habe, wie würdest du es machen?! Lassen Sie uns unsere Ansätze diversifizieren und alle Möglichkeiten kennenlernen, wie wir im Web entwickeln können. Erstellen Sie eine Demo, twittern Sie mir Ihre Version und ich füge sie unten im Abschnitt Community-Remixe hinzu.

Community-Remixe