====== 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); } }