====== LU13f - Scroll-gesteuerte Animationen ======
{{ :de:modul:m291:learningunits:lu13:theorie:scroll_animation.gif?nolink | Gif: Scroll Animation}}
Mit ''animation-timeline: view()'' wird der Fortschritt einer Animation nicht durch Zeit gesteuert, sondern durch die **Position des Elements im Viewport**. Das Element animiert herein, wenn es beim Scrollen sichtbar wird – ganz ohne JavaScript.
===== Grundprinzip =====
@keyframes aufzoomen {
0%, 100% { transform: scale(0.7); opacity: 0.4; }
50% { transform: scale(1); opacity: 1; }
}
.kachel {
animation: aufzoomen linear;
animation-timeline: view(block);
}
Die Animation ist direkt an die Scroll-Position des Elements geknüpft:
^ Animations-Fortschritt ^ Bedeutung ^
| ''0 %'' | Element tritt von unten in den Viewport ein |
| ''50 %'' | Element befindet sich vollständig im sichtbaren Bereich |
| ''100 %'' | Element verlässt den Viewport nach oben |
Bei ''animation-timeline: view()'' bestimmt die Scrollgeschwindigkeit des Nutzers, wie schnell die Animation abgespielt wird. Deshalb wird als Timing-Funktion immer ''linear'' verwendet – ''ease'' oder ''ease-in-out'' hätten hier keinen sinnvollen Effekt.
===== Häufige Fehlerquellen =====
''animation-timeline: view()'' funktioniert nicht, wenn ein übergeordnetes Element einen neuen **Scroll-Container** erstellt. Das passiert immer dann, wenn ''overflow: hidden'' auf einem Elternelement gesetzt ist.
^ Problem ^ Ursache ^ Lösung ^
| Animation startet nicht | ''overflow: hidden'' auf einem Elternelement | ''overflow: clip'' verwenden |
| Animation startet nicht | ''overflow-x: hidden'' auf '''' | ''overflow-x: clip'' verwenden |
| Animation startet nicht | ''height: 100%'' auf ''html, body'' | ''min-height: 100%'' verwenden |
===== Vollständiges Beispiel =====
/* main.css */
html, body {
min-height: 100%; /* wichtig: nicht height: 100% */
}
/* Cards.vue */
main {
overflow-x: clip; /* wichtig: nicht overflow-x: hidden */
}
/* CardItem.vue */
@keyframes reinzoomen {
0%, 100% { transform: scale(0.65); }
50% { transform: scale(1); }
}
@media screen and (max-width: 640px) {
article {
animation: reinzoomen linear;
animation-timeline: view(block);
}
}