Eine grundlegende Übersicht zum Erstellen einer responsiven horizontalen Bildlaufleiste für Fernseher, Smartphones, Computer usw.
In diesem Beitrag möchte ich Ihnen zeigen, wie Sie horizontales Scrollen für das Web schaffen können, das minimal, responsiv, barrierefrei ist und in Browsern und Plattformen (z. B. Fernsehern) funktioniert. Demo ansehen
Wenn du lieber ein Video ansiehst, findest du hier eine YouTube-Version dieses Beitrags:
Übersicht
Wir entwickeln ein horizontales Scroll-Layout für Miniaturansichten von Medien oder Produkten. Die Komponente beginnt als einfache <ul>
-Liste, wird aber mit CSS in eine zufriedenstellende und flüssige Bildanzeige umgewandelt, bei der Bilder präsentiert und in ein Raster eingefügt werden. JavaScript wurde hinzugefügt, um Interaktionen mit dem ständigen Index zu erleichtern, sodass Tastaturnutzer mehr als 100 Elemente überspringen müssen.
Außerdem wird die experimentelle Medienabfrage prefers-reduced-data
verwendet, um den Medien-Scroller in ein einfaches Scrollen für den Titel umzuwandeln.
Mit barrierefreiem Markup beginnen
Ein Medien-Scroller besteht nur aus wenigen Hauptkomponenten, einer Liste mit Elementen. Eine Liste kann in ihrer einfachsten Form auf der ganzen Welt verbreitet und von allen klar konsumiert werden. Nutzer, die auf dieser Seite landen, können eine Liste durchsuchen und auf einen Link klicken, um sich einen Artikel anzusehen. Das ist unsere Basis.
Eine Liste mit einem <ul>
-Element senden:
<ul class="horizontal-media-scroller">
<li></li>
<li></li>
<li></li>
...
<ul>
Mit einem <a>
-Element können Sie die Listenelemente interaktiv gestalten:
<li>
<a href="#">
...
</a>
</li>
Verwenden Sie ein <figure>
-Element, um ein Bild und seine Bildunterschrift semantisch darzustellen:
<figure>
<picture>
<img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
</picture>
<figcaption>Legends</figcaption>
</figure>
Beachten Sie die Attribute alt
und loading
auf dem <img>
. Der Alt-Text für einen Medien-Scroller ist eine Möglichkeit zur Verbesserung der Nutzerfreundlichkeit, um dem Thumbnail zusätzlichen Kontext zu verleihen. Er kann auch als Ersatztext verwendet werden, wenn das Bild nicht geladen wurde, oder als gesprochene Benutzeroberfläche für Nutzer, die Hilfstechnologien wie Screenreader verwenden. Weitere Informationen finden Sie unter Fünf goldene Regeln für konformen Alt-Text.
Das Attribut loading
akzeptiert das Keyword lazy
, um anzugeben, dass diese Bildquelle nur abgerufen werden soll, wenn sich das Bild im Darstellungsbereich befindet. Das kann bei großen Listen sehr praktisch sein, da Nutzer nur Bilder für Elemente herunterladen, die sie in den Blick gescrollt haben.
Die Farbschema-Präferenzen des Nutzers unterstützen
Verwenden Sie color-scheme
als <meta>
-Tag, um dem Browser zu signalisieren, dass für Ihre Seite sowohl der helle als auch der dunkle User-Agent-Stil verwendet werden soll. Es ist ein kostenloser dunkler oder heller Modus, je nachdem, wie Sie es sehen:
<meta name="color-scheme" content="dark light">
Das Meta-Tag liefert das frühestmögliche Signal, sodass der Browser eine dunkle Standard-Canvas-Farbe auswählen kann, wenn der Nutzer ein dunkles Design bevorzugt. Das bedeutet, dass beim Wechseln zwischen den Seiten der Website kein weißer Canvas-Hintergrund zwischen den Ladevorgängen angezeigt wird. Das dunkle Design bleibt nach dem Laden erhalten und ist angenehmer für die Augen.
Weitere Informationen von Thomas Steiner finden Sie unter https://web.dev/color-scheme/.
Inhalt hinzufügen
Anhand der oben beschriebenen Inhaltsstruktur von ul > li > a > figure > picture > img
besteht die nächste Aufgabe darin, Bilder und Titel hinzuzufügen, die sich scrollen lassen. Ich habe die Demo mit statischen Platzhalterbildern und Text gefüllt, Sie können sie aber auch mit Ihrer bevorzugten Datenquelle betreiben.
Stil mit CSS hinzufügen
Jetzt ist es an der Zeit, dass das Preisvergleichsportal diese allgemeine Liste von Inhalten in eine Website umwandelt. Netflix, App-Shops und viele weitere Websites und Apps verwenden horizontal scrollbare Bereiche, um den Darstellungsbereich mit Kategorien und Optionen zu füllen.
Scroller-Layout erstellen
Achten Sie darauf, dass Inhalte in Layouts nicht abgeschnitten werden und dass Text nicht durch Ellipsen abgeschnitten wird. Viele Fernseher haben Medien-Scroller wie diesen, aber allzu oft werden Inhalte durch Auslassungen gekürzt. Das ist bei diesem Layout nicht der Fall. Außerdem können die Medieninhalte die Spaltengröße überschreiben, sodass ein Layout flexibel genug ist, um viele interessante Kombinationen zu ermöglichen.
Der Container ermöglicht das Überschreiben der Spaltengröße, indem die Standardgröße als benutzerdefiniertes Attribut angegeben wird. Bei diesem Rasterlayout wird die Spaltengröße festgelegt. Es werden nur Abstände und Richtung verwaltet:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2); /* parent owned value for children to be relative to*/
margin: 0;
}
Die benutzerdefinierte Eigenschaft wird dann vom <picture>
-Element verwendet, um unser grundlegendes Seitenverhältnis zu erstellen – ein Rechteck:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
& picture {
inline-size: var(--size);
block-size: var(--size);
}
}
Mit nur wenigen weiteren Stilen können Sie den Medien-Scroller fertigstellen:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
& > li {
display: inline-block; /* removes the list-item bullet */
}
& picture {
inline-size: var(--size);
block-size: var(--size);
}
}
Wenn overflow
festgelegt ist, wird <ul>
so konfiguriert, dass Scrollen und die Tastaturnavigation durch die Liste möglich sind. Dann wird die ::marker
für jedes direkte untergeordnete <li>
-Element entfernt, indem der neue Anzeigetyp inline-block
abgerufen wird.
Die Bilder sind jedoch noch nicht responsiv und platzen aus den Boxen heraus, in denen sie sich befinden. Optimieren Sie sie mit bestimmten Größen, Anpassungs- und Rahmenstilen sowie einem Hintergrundverlauf für das Lazy Loading:
img {
/* smash into whatever box it's in */
inline-size: 100%;
block-size: 100%;
/* don't squish but do cover the space */
object-fit: cover;
/* soften the edges */
border-radius: 1ex;
overflow: hidden;
/* if empty, show a gradient placeholder */
background-image:
linear-gradient(
to bottom,
hsl(0 0% 40%),
hsl(0 0% 20%)
);
}
Abstand beim Scrollen
Die Ausrichtung am Seiteninhalt und eine scrollbare Oberfläche von Rand zu Rand sind entscheidend für eine harmonische und minimalistische Komponente.
Verwenden Sie für das Scroll-Layout von Rand zu Rand, das mit unserer Typografie und unseren Layoutlinien übereinstimmt, padding
, die mit der scroll-padding
übereinstimmt:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
padding-inline: var(--gap);
scroll-padding-inline: var(--gap);
padding-block: calc(var(--gap) / 2); /* make space for scrollbar and focus outline */
}
Fehlerbehebung beim horizontalen Scroll-Padding Wie oben gezeigt, sollte es ganz einfach sein, einen Scrollcontainer zu füllen. Es gibt jedoch noch offene Kompatibilitätsprobleme (in Chromium 91 und höher behoben). Hier finden Sie einen kurzen Überblick über die Entwicklung. Kurz gesagt: In einer Scrollansicht wurde der Abstand nicht immer berücksichtigt.
Um Browser dazu zu bringen, den Abstand am Ende des Scrollers zu platzieren, richte ich das letzte Element in jeder Liste an und füge ein Pseudo-Element mit dem gewünschten Abstand hinzu.
.horizontal-media-scroller > li:last-of-type figure {
position: relative;
&::after {
content: "";
position: absolute;
inline-size: var(--gap);
block-size: 100%;
inset-block-start: 0;
inset-inline-end: calc(var(--gap) * -1);
}
}
Die Verwendung logischer Eigenschaften ermöglicht es dem Medien-Scroller, in jedem Schreibmodus und jeder Dokumentrichtung zu arbeiten.
Scroll Snap
Ein scrollbarer Container mit Überlauf kann mit einer Zeile CSS zu einem anschnappenden Darstellungsbereich werden. Die untergeordneten Elemente müssen dann angeben, wie sie sich an diesem Darstellungsbereich ausrichten möchten.
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
padding-inline: var(--gap);
scroll-padding-inline: var(--gap);
padding-block-end: calc(var(--gap) / 2);
scroll-snap-type: inline mandatory;
& figure {
scroll-snap-align: start;
}
}
Fokus
Die Inspiration für diese Komponente stammt von ihrer enormen Beliebtheit auf Fernsehern, in App Stores und anderen Quellen. Viele Videospielplattformen verwenden einen Medien-Scroller, der diesem sehr ähnlich ist, als primäres Startbildschirm-Layout. Der Fokus ist hier ein wichtiger UX-Moment, keine kleine Ergänzung. Stellen Sie sich vor, Sie verwenden diesen Medien-Scroller auf der Couch mit einer Fernbedienung. Sie können diese Interaktion mit einigen kleinen Verbesserungen versehen:
.horizontal-media-scroller a {
outline-offset: 12px;
&:focus {
outline-offset: 7px;
}
@media (prefers-reduced-motion: no-preference) {
& {
transition: outline-offset .25s ease;
}
}
}
Dadurch wird der Fokus-Umrissstil 7px
vom Feld weggesetzt, sodass er etwas Platz hat. Wenn der Nutzer keine Bewegungspräferenzen zum Reduzieren von Bewegungen hat, wird der Offset verschoben, um dem Fokusereignis eine subtile Bewegung zu verleihen.
Roving-Index
Nutzer von Gamepads und Tastaturen benötigen bei diesen langen Listen mit scrollbaren Inhalten und Optionen besondere Aufmerksamkeit. Das gängige Muster zur Lösung dieses Problems wird als Roaming-Index bezeichnet. Dies ist der Fall, wenn ein Container mit Elementen per Tastatureingabe fokussiert ist, aber jeweils nur ein untergeordnetes Element den Fokus behalten darf. Mit dieser Funktion können Sie die potenziell lange Liste von Elementen überspringen, anstatt mehr als 50 Mal die Tabulatortaste zu drücken, um das Ende zu erreichen.
Der erste Scroller der Demo enthält 300 Elemente. Wir können es besser machen, als sie alle durchlaufen zu lassen, um zum nächsten Abschnitt zu gelangen.
Dazu müssen in JavaScript Tastatur- und Fokusereignisse beobachtet werden. Ich habe eine kleine Open-Source-Bibliothek auf npm erstellt, um diese Nutzererfahrung zu vereinfachen. So verwenden Sie sie für die drei Bildlaufleisten:
import {rovingIndex} from 'roving-ux';
rovingIndex({
element: someElement
});
In dieser Demo wird das Dokument nach den Bildlaufleisten abgefragt und für jede davon wird die Funktion rovingIndex()
aufgerufen. Übergeben Sie das Element rovingIndex()
, um die Umgebung zu erhalten, z. B. einen Listencontainer und eine Zielabfrageauswahl, falls die Fokusziele keine direkten Nachfolger sind.
document.querySelectorAll('.horizontal-media-scroller')
.forEach(scroller =>
rovingIndex({
element: scroller,
target: 'a',
}))
Weitere Informationen zu diesem Effekt finden Sie in der Open-Source-Bibliothek roving-ux.
Seitenverhältnis
Zum Zeitpunkt der Erstellung dieses Beitrags ist die Unterstützung für aspect-ratio
in Firefox deaktiviert, aber in Chromium-Browsern oder auf Set-Top-Boxen verfügbar. Da im Medien-Scroller-Rasterlayout nur Richtung und Abstand angegeben werden, kann sich die Größe in einer Medienabfrage ändern, in der die Unterstützung des Seitenverhältnisses geprüft wird.
Progressive Enhancement in einige dynamischere Medien-Scroller ein.
@supports (aspect-ratio: 1) {
.horizontal-media-scroller figure > picture {
inline-size: auto; /* for a block-size driven ratio */
aspect-ratio: 1; /* boxes by default */
@nest section:nth-child(2) & {
aspect-ratio: 16/9;
}
@nest section:nth-child(3) & {
/* double the size of the others */
block-size: calc(var(--size) * 2);
aspect-ratio: 4/3;
/* adjust size to fit more items into the viewport */
@media (width <= 480px) {
block-size: calc(var(--size) * 1.5);
}
}
}
}
Wenn der Browser die aspect-ratio
-Syntax unterstützt, werden die Bilder im Medien-Scroller auf aspect-ratio
-Größe umgestellt. Mit der Syntax für das Nesting von Vorlagen ändert jedes Bild sein Seitenverhältnis, je nachdem, ob es sich um die erste, zweite oder dritte Zeile handelt. Mit der verschachtelten Syntax können Sie auch einige kleine Anpassungen des Darstellungsbereichs direkt mit der anderen Größenlogik festlegen.
Da die Funktion in mehr Browser-Engines verfügbar ist, wird mit diesem CSS ein einfach zu verwaltendes, aber visuell ansprechenderes Layout gerendert.
Reduzierte Daten bevorzugt
Diese nächste Methode ist in Canary nur über ein Flag verfügbar. Ich möchte Ihnen aber zeigen, wie ich mit wenigen Zeilen CSS die Seitenladezeit und die Datennutzung erheblich reduzieren konnte. Mit der Medienabfrage prefers-reduced-data
von Ebene 5 kann abgefragt werden, ob sich das Gerät in einem reduzierten Datenstatus befindet, z. B. in einem Datensparmodus. Ist dies der Fall, kann ich das Dokument
ändern und die Bilder ausblenden.
figure {
@media (prefers-reduced-data: reduce) {
& {
min-inline-size: var(--size);
& > picture {
display: none;
}
}
}
}
Die Inhalte sind weiterhin aufrufbar, ohne dass die großen Bilder heruntergeladen werden müssen. So sieht die Website aus, bevor das prefers-reduced-data
-CSS hinzugefügt wird:
(7 Anfragen, 100 KB Ressourcen in 131 ms)
So sieht die Websiteleistung nach dem Hinzufügen des prefers-reduced-data
-CSS aus:
(71 Anfragen, 1,2 MB Ressourcen in 1.07 s)
64 weniger Anfragen, das entspricht den etwa 60 Bildern im Viewport (Tests auf einem Breitbilddisplay) dieses Browsertabs, eine Beschleunigung des Seitenladevorgangs um etwa 80 % und 10 % der Datenübertragung. Ziemlich leistungsstarkes CSS.
Fazit
Jetzt, da du weißt, wie ich das gemacht habe, wie würdest du es tun?! 🙂
Lassen Sie uns unsere Ansätze diversifizieren und alle Möglichkeiten kennenlernen, wie Sie im Web entwickeln können. Erstelle einen Codepen oder hosten Sie Ihre eigene Demo, twittern Sie mich mit dem Code und ich füge ihn dem Abschnitt Community-Remixe unten hinzu.
Quelle
Remixe der Community
Noch keine Aktivität hierzu.