Eine Scroll-Fortschrittsanzeige ist ein gängiges Muster für Benutzeroberflächen, das den Fortschritt des Nutzers in einem scrollbaren Dokument oder Container visuell darstellt. Wenn der Nutzer scrollt, wird ein visuelles Element aktualisiert, um seine Position widerzuspiegeln. So erhält er einen klaren und intuitiven Eindruck davon, wie viele Inhalte er sich bereits angesehen hat und wie viele noch übrig sind.
Implementierung
Für eine Scroll-Fortschrittsanzeige benötigen Sie zwei Dinge:
- Ein Element, das als Fortschrittsanzeige dient. Dieses Element ist normalerweise
position: fixedoderposition: absolute, damit es beim Scrollen sichtbar bleibt. - Eine Animation, die mit der Scrollposition verknüpft ist.
So können Sie das erreichen:
- Erstellen Sie zuerst ein HTML-Element, das als Fortschrittsanzeige dient. Dieses Element kann nach Ihren Wünschen gestaltet werden.
- Definieren Sie als Nächstes in Ihrem CSS eine
@keyframes-Animation, die die Fortschrittsanzeige skaliert. Ein gängiger Ansatz ist, das Element vonscaleX(0)aufscaleX(1)zu skalieren. - Wende diese Animation schließlich auf das Element für die Fortschrittsanzeige an und setze die
animation-timelineauf eine Scroll-Zeitachse. Dadurch wird der Browser angewiesen, den Fortschritt der Animation basierend auf der Scrollposition des nächstgelegenen übergeordneten Scrollers zu steuern.
Beispielcode
Mit diesem Code wird das #progress-Element beim Scrollen mithilfe einer anonymen Scroll-Zeitachse vergrößert, die mit der Funktion scroll() erstellt wird.
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: scroll())) {
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
#progress {
position: fixed;
left: 0; top: 0;
width: 100%; height: 1em;
background: red;
transform-origin: 0 50%;
animation: grow-progress auto linear;
animation-timeline: scroll();
}
}
}
Aufgrund ihrer Position im DOM verfolgt die Funktion scroll() den nächstgelegenen übergeordneten Scroller in Richtung block, was hier der Root-Scroller ist.
<body>
<!-- MANDATORY: Purely decorative visual scroll progress bars MUST set aria-hidden="true" to remove the empty element from the assistive technology reading tree -->
<div id="progress" aria-hidden="true"></div>
</body>
Mit diesem Code wird das #progress-Element beim Scrollen mithilfe einer benannten Scroll-Zeitachse vergrößert, die mit der Property scroll-timeline erstellt wurde.
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: scroll())) {
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
:root {
scroll-timeline: --tl block;
}
#progress {
position: fixed;
left: 0; top: 0;
width: 100%; height: 1em;
background: red;
transform-origin: 0 50%;
animation: grow-progress auto linear;
animation-timeline: --tl;
}
}
}
Best Practices
Wenn Sie scrollbasierte Animationen verwenden, sollten Sie einige Best Practices beachten, um eine reibungslose und barrierefreie Nutzung zu ermöglichen:
- DO include feature detection: Not all browsers support scroll-driven animations. Verwenden Sie
@supports (animation-timeline: scroll()), um die Unterstützung zu prüfen, und stellen Sie einen Fallback für Browser bereit, die die Funktion nicht unterstützen.- Verwenden Sie NICHT das Paket
scroll-timeline-polyfillfür die Fallback-Strategie, da es nicht vollständig ist und viele bekannte Probleme aufweist. - Wenn die Animation nur dekorativ ist, entscheide dich für die progressive Verbesserung und stelle KEIN Fallback bereit.
- Verwenden Sie NICHT das Paket
- ENTFERNEN Sie rein dekorative Elemente aus dem Lesefluss von Hilfstechnologien: Wenden Sie
aria-hidden="true"auf rein visuelle Scroll-Indikatoren an, damit Screenreader nicht auf leere, unbenannte Knoten stoßen. - DO respect user preferences: Some users prefer to have less motion on the web. Verwenden Sie die Medienabfrage
prefers-reduced-motion, um Ihre Animationen für diese Nutzer zu deaktivieren oder zu reduzieren. - DO try to animate only performant CSS properties: For the smoothest animations, stick to animating properties that can be handled by the browser's compositor thread, such as
transformandopacity. Das Animieren anderer Attribute wiewidthoderheightkann zu Leistungsproblemen führen. - RICHTIG: Verwenden Sie die richtige Deklarationsreihenfolge. Wenn Sie die Kurzschreibweise
animationverwenden, deklarieren Sieanimation-timelinedanach, um zu verhindern, dass die Kurzschreibweise die Zeitachse zurücksetzt.
Wenn Sie die Funktion scroll() verwenden, um eine scrollbasierte Animation zu erstellen, gilt Folgendes:
- OPTIONAL: Geben Sie den Scroller explizit an. Wenn Sie nicht den nächstgelegenen übergeordneten Scroller verwenden möchten, geben Sie mit
scroll(root)oderscroll(self)explizit an, welchen Scroller Sie verwenden möchten.- Wenn
root,nearestoderselfnicht ausreichen, verwenden Sie eine benannte Scroll-Zeitachse.
- Wenn
- OPTIONAL: Geben Sie die zu verfolgende Achse explizit an. Wenn Sie nicht die Standardachse
blockverwenden (z. B. bei einem horizontalen Scroller), geben Sie mitscroll(block)oderscroll(inline)explizit an, welche Achse verfolgt werden soll.
Wenn Sie die Eigenschaft scroll-timeline verwenden, um eine scrollbasierte Animation zu erstellen:
- Verwenden Sie für den Namen ein CSS-
<dashed-ident>. (EMPFOHLEN) - OPTIONAL: Achte darauf, die zu verfolgende Achse explizit anzugeben. Wenn du nicht die Standardachse
blockverwendest (z. B. bei einem horizontalen Scroller), gib explizit an, welche Achse mitscroll-timeline-axisverfolgt werden soll. - DO: Achten Sie darauf, dass der Suchbereich funktioniert. Wenn das Element, das die
scroll-timelinedeklariert, kein flacher Baum-Ancestor des animierten Elements ist, erhöhen Sie die Sichtbarkeit des Namens derscroll-timeline, indem Sietimeline-scopefür einen gemeinsamen Ancestor verwenden.
Fallback-Strategien
Für Browser, die keine scrollgesteuerten Animationen unterstützen, können Sie einen Fallback verwenden, um die visuellen Effekte nachzubilden. Die Fallbacks werden in der Regel entweder mit einem Scroll-Listener (für ScrollTimeline-Effekte) oder der IntersectionObserver API (für ViewTimeline-Effekte) erstellt.
Verwenden Sie in Browsern mit integrierter Unterstützung für scrollgesteuerte Animationen IMMER die native CSS-Implementierung, da diese leistungsfähiger ist.
Beachten Sie, dass nicht jeder Effekt mit dem Fallback-Ansatz nachgebildet werden kann.
Speziell für diesen Anwendungsfall wird im folgenden Script der Fallback für Browser angewendet, die keine scrollgesteuerten Animationen unterstützen. Dabei wird ein Scroll-Listener verwendet, um die Scrollposition des Stammelements zu verfolgen und die Eigenschaft transform der Fortschrittsanzeige entsprechend zu aktualisieren.
<script>
if (!CSS.supports('animation-timeline', 'scroll()')) {
const progress = document.querySelector('#progress');
window.addEventListener('scroll', () => {
const scrollable = document.documentElement.scrollHeight - window.innerHeight;
const scrolled = window.scrollY;
const progressPercentage = (scrolled / scrollable);
progress.style.transform = `scaleX(${progressPercentage})`;
});
}
</script>