Sie haben die Theorie zu CSS Keyframe Animationen gelesen. Jetzt wenden Sie das Gelernte direkt an: Sie erweitern Ihr bestehendes FAQ-Accordion mit drei Animationen, die die User-Experience verbessern.
| Merkmal | Beschreibung |
|---|---|
| Zeit | 20–25 Minuten |
| Sozialform | Einzelarbeit – Austausch und Hilfe mit Sitznachbarn erlaubt |
| Voraussetzung | Accordion lädt Daten von MockAPI (LU11 / LU12 Phase 1 abgeschlossen) |
Am Ende dieses Auftrags hat Ihr Accordion drei Animationen:
| Animation | Datei | Wann |
|---|---|---|
| Spinner | Accordion.vue | Während die Daten von der API laden |
| Fade-in mit Treppeneffekt | Accordion.vue | Wenn die FAQ-Items nach dem Laden erscheinen |
| Einblenden | AccordionItem.vue | Wenn eine Antwort aufgeklappt wird |
Öffnen Sie Accordion.vue. Fügen Sie im <style>-Bereich folgende Styles ein:
/* Spinner-Animation */ @keyframes spin { to { transform: rotate(360deg); } } .loading-wrapper { display: flex; flex-direction: column; align-items: center; gap: 0.75rem; padding: 2rem 0; color: #888; font-size: 0.9rem; } .loading-spinner { width: 36px; height: 36px; border: 4px solid #e0e0e0; border-top-color: #444; border-radius: 50%; animation: spin 0.75s linear infinite; }
Warum keinfrom? Der Spinner startet beirotate(0deg)— das ist der CSS-Default. Den Startwert müssen wir nicht explizit schreiben (Partial Keyframes Trick aus der Theorie).
Warumlinear? Bei einem Spinner würdeease-in-outdas Drehen ungleichmässig wirken lassen — als würde er stocken und beschleunigen.linearhält die Drehung konstant flüssig.
Ersetzen Sie die bisherige Ladeanzeige „Daten werden geladen…„ durch den animierten Spinner:
Öffnen Sie DevTools (F12) → Reiter Network → Geschwindigkeit auf Slow 3G stellen. Laden Sie die Seite neu. Der Spinner sollte sichtbar sein, bevor die FAQ-Items erscheinen. Stellen Sie die Geschwindigkeit anschliessend wieder zurück.
Wenn die Daten geladen sind und die Items erscheinen, wirkt es eleganter, wenn sie nicht alle gleichzeitig aufpoppen — sondern leicht versetzt nacheinander eingeblendet werden.
Fügen Sie in Accordion.vue → <style> hinzu:
/* Fade-in Keyframe */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } } /* Wird auf jedes AccordionItem angewendet */ .faq-item { animation: fadeInUp 0.4s ease both; animation-delay: calc(var(--i) * 70ms); }
bothstattforwards: Weil wir einenanimation-delaygesetzt haben, würden die Items ohnebothkurz mitopacity: 1aufblitzen, bevor ihre Animation startet.bothstellt sicher, dass sie bereits während der Wartezeit im Startzustand (opacity: 0) bleiben.
Damit der gestaffelte Delay funktioniert, muss jedes Item wissen, an welcher Position es in der Liste steht. Übergeben Sie den Index aus v-for als CSS Custom Property:
<!-- Vorher: --> <AccordionItem v-for="item in faqItems" :key="item.id" :faq="item" /> <!-- Nachher: --> <AccordionItem v-for="(item, index) in faqItems" :key="item.id" :faq="item" class="faq-item" :style="{ '--i': index }" />
Laden Sie die Seite neu (Slow 3G hilft auch hier). Die FAQ-Items sollten nun nacheinander von unten eingeblendet werden — jedes leicht nach dem vorherigen.
Fragen zum Verstehen:
70ms auf 200ms ändern? Und auf 0ms?calc(var(–i) * 70ms) konkret für das dritte Item (Index 2)?Das Öffnen eines Accordion-Items soll ebenfalls animiert sein: Die Antwort soll sanft eingeblendet werden, statt abrupt zu erscheinen.
Öffnen Sie AccordionItem.vue. Fügen Sie im <style>-Bereich hinzu:
@keyframes fadeIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } } .accordion-body { animation: fadeIn 0.25s ease forwards; }
KleinertranslateY-Wert: Der Text bewegt sich beim Öffnen leicht von oben nach unten — das gibt der Bewegung eine Richtung, die zum Aufklappen passt.
Klicken Sie auf ein FAQ-Item. Der Antwort-Text sollte nun weich eingeblendet werden.
Frage: Was passiert ohne forwards? Probieren Sie es aus, indem Sie forwards entfernen und die Animation beobachten.
Als Alternative zum Spinner können Sie drei springende Punkte als Ladeanzeige verwenden. Ersetzen Sie in Accordion.vue die Spinner-Styles und das Template:
@keyframes bounce { 0%, 80%, 100% { transform: translateY(0); } 40% { transform: translateY(-10px); } } .loading-dots { display: flex; gap: 8px; justify-content: center; padding: 2rem 0; } .loading-dots span { width: 10px; height: 10px; border-radius: 50%; background: #888; animation: bounce 1.2s ease-in-out infinite; } .loading-dots span:nth-child(2) { animation-delay: 0.2s; } .loading-dots span:nth-child(3) { animation-delay: 0.4s; }
<div v-if="isLoading" class="loading-dots"> <span></span> <span></span> <span></span> </div>
Frage: Warum sind die Keyframes 0% und 100% identisch? Was würde passieren, wenn 100% auf translateY(-10px) gesetzt würde?
Unter folgendem Link können Sie meine finale Umsetzung des Accordions (Accordion.vue und AccordionItem.vue) herunterladen und mit Ihrem eigenen Code vergleichen.