Eine grundlegende Übersicht zum Erstellen einer responsiven horizontalen Bildlaufleiste für Fernseher, Smartphones, Computer usw.
In diesem Beitrag möchte ich meine Gedanken zu Möglichkeiten zum Erstellen horizontal scrollbarer Websites teilen, die minimalistisch, responsiv, barrierefrei und plattformübergreifend (z. B. auf Fernsehern) funktionieren. 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 wird hinzugefügt, um die Interaktionen mit dem Suchindex zu erleichtern und Nutzern mit Tastatur das Überspringen von mehr als 100 Elementen zu ermöglichen.
Außerdem wird die experimentelle Medienabfrage prefers-reduced-data
verwendet, um den Medien-Scroller in einen schlanken Titel-Scroller umzuwandeln.
Mit barrierefreiem Markup beginnen
Ein Medien-Scroller besteht nur aus wenigen Hauptkomponenten, einer Liste mit Elementen. Eine Liste in ihrer einfachsten Form kann auf der ganzen Welt verbreitet und von allen klar verstanden 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>
Liste interaktiv mit einem <a>
-Element 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. Er kann dem Thumbnail zusätzlichen Kontext verleihen oder als Ersatztext dienen, wenn das Bild nicht geladen wurde. Außerdem bietet er eine 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.
Farbschema 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üheste Signal, damit 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 finden Sie bei Thomas Steiner 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 Text in Layouts nicht abgeschnitten wird und dass Sie Text nicht durch Ellipsen abkürzen. Viele Fernseher haben Medien-Scroller wie diesen, aber allzu oft werden Inhalte durch Auslassungen gekürzt. Dieses Layout tut das nicht. Außerdem können die Medieninhalte die Spaltengröße überschreiben, sodass ein Layout flexibel genug ist, um viele interessante Kombinationen zu ermöglichen.
Im Container kann die Spaltengröße überschrieben werden, indem die Standardgröße als benutzerdefinierte Eigenschaft 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 Property wird dann vom <picture>
-Element verwendet, um das Basisseitenverhä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 Sie overflow
festlegen, wird das <ul>
so eingerichtet, dass die Liste durch Scrollen und Tastaturnavigation durchsucht werden kann. Anschließend wird das ::marker
jedes direkten untergeordneten <li>
-Elements entfernt, indem ein neuer Darstellungstyp von inline-block
festgelegt wird.
Die Bilder sind jedoch noch nicht responsiv und platzen aus den Boxen heraus, in denen sie sich befinden. Sie können sie mit verschiedenen Größen, Anpassungen, Rahmenstilen und einem Hintergrundverlauf für das Lazy-Loading anpassen:
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%)
);
}
Scroll-Abstand
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 der gewünschten Abstandsgröße an.
.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);
}
}
Mithilfe logischer Eigenschaften kann der Medien-Scroller in jedem Schreibmodus und in jeder Dokumentausrichtung verwendet werden.
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 an diesem Darstellungsbereich ausgerichtet werden sollen.
.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 aus ihrer enormen Beliebtheit auf Fernsehern, in App-Shops und mehr. 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 Einstellungen zur Reduzierung von Bewegungen festgelegt hat, wird der Offset übergangen, wodurch dem Fokusereignis eine subtile Bewegung verliehen wird.
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. Ein Container mit Elementen ist über die Tastatur fokussiert, aber nur ein untergeordnetes Element darf gleichzeitig den Fokus haben. 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 überwacht 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 rovingIndex()
das Element, um die roving-Funktion zu aktivieren, z. B. einen Listencontainer, und eine Auswahl für die Zielabfrage, falls die Fokusziele keine direkten Nachkommen 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 Verbesserung durch dynamischere Medien-Scroller.
@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 die Größe aspect-ratio
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 prefers-reduced-data
-Medienabfrage von Ebene 5 kann abgefragt werden, ob sich das Gerät in einem Zustand mit reduzierter Datennutzung befindet, z. B. im Datensparmodus. Falls ja, kann ich das Dokument ändern und in diesem Fall 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 wurde:
(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 Sekunden)
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. Ein ziemlich leistungsstarkes CSS.
Fazit
Jetzt, da Sie wissen, wie ich das gemacht habe, wie würden Sie es machen? 🙂
Lassen Sie uns unsere Ansätze diversifizieren und alle Möglichkeiten kennenlernen, wie Sie im Web entwickeln können. Erstelle einen Codepen oder hoste deine eigene Demo, tweete mir einen Link dazu und ich füge sie unten in den Abschnitt „Community-Remixe“ ein.
Quelle
Remixe der Community
Noch keine Aktivität hierzu.