CSS, HTML und Javascript mit {stil}

CSS Slideshow mit Timeline

CSS Slideshow ohne Javascript Erklärt die Keyframes anhand einer Timeline

Bei komplexen CSS-Keyframe-Animationen wie einer Slideshow verliert man schnell den Überblick, wie die einzelnen Schritte ineinandergreifen.

Was uns fehlt, ist eine Timeline wie einst in Adobe Flash, um den Ablauf der Keyframe-Animation gut zu erkennen.

Eine einfache Slideshow mit fünf Slides ist noch überschaubar, aber man braucht schon die Finger beider Hände, um die Bewegung, das Auftauchen und Verschwinden der einzelnen Slides durch CSS Keyframes zu synchronisieren.

simply an A
Gib mir ein A
kaktus
Mein kleiner Kaktus
Rote Uhr
Roter Wecker
Umschlag und Stempel
Brief und Siegel
Schwarze Box
Black Box

Animation für ein Bild: 5 sek

5 Bilder à 5 Sekunden = 25 sek Dauer der Animation

Jedes Bild läuft innerhalb einer Sekunde von unten in das Slideshow-Fenster hinein (Slide In), bleibt für drei Sekunden sichtbar und braucht dann wieder eine Sekunde, um nach oben außerhalb des sichtbaren Ausschnitts zu verschwinden (Slide Out).

CSS Keyframes Timeline Zeigt die Folge der Keyframes und ihre Dauer

Die Keyframes liegen zwischen 0 bis 100% – die Animation läuft in einem 4%-Takt.

Slideshow HTML-Markup: figure und figcation

Einfaches HTML: figure und figcaption innerhalb des Rahmens
<div id="slider">
   <div id="onframe">
      <figure class="animate1">
         <img src="a.jpg" width="680" height="360" alt="simply an A">
         <figcaption class="label">Gib mir ein A</figcaption>
      </figure>
      …
      <figure class="animate5">
         <img src="pack.jpg" width="680" height="360" alt="Schwarze Box">
         <figcaption class="label">Black Box</figcaption>
      </figure>
   </div>  <!-- /#onframe -->
   <div class="progress-bar"></div>  <!-- Fortschrittsbalken -->
</div>  <!-- /#Slider -->

Das CSS für den Slider und den Slideshow-Rahmen

#onframe {
   overflow: hidden;
   height: 360px;
}
#slider {
   background: #fff;
   border: 5px solid #eaeaea;
   box-sizing:border-box;
   height: 370px;
   width: 90%;
   margin: 40px auto 0;
   overflow: hidden;
   position: relative;
}

#slider figure {
   width: 680px;  /* Breite des Bildes */
   height: 360px; /* Höhe des Bildes */
   position: absolute;
   margin: 0;
   bottom: 360px; /* Originalposition - Nicht im sichtbaren Ausschnitt */
   left: calc(50% - 360px); /* Setzt Bild in die Mitte des sichtbaren Ausschnitts */
}

Die Bilder sitzen horizontal zentriert innerhalb des Sliders. CSS calc berechnet die Position in der Mitte.

left: calc(50% - 360px); 

Auf kleinen Monitoren passt sich die Slideshow nur in der Horizontalen an und wird schmaler. Das Bild wird dabei rechts und links abgeschnitten, die Mitte bleibt stehen.

Bevor die Slideshow anläuft, sitzen die Bilder unterhalb des sichtbaren Rahmens.

bottom: 360px;

Die Keyframe-Animation

Jedes Bild läuft innerhalb einer Sekunde in den sichtbaren Rahmen hinein, bleibt für drei Sekunden stehen, läuft in der fünften Sekunde wieder aus dem Rahmen. Danach muss das Bild wieder auf seine Startposition unterhalb der Slideshow.

Keyframe-Animation
#slider .animate1 {
   animation: cycle1 25s linear infinite;
}

#slider .animate2 {
   animation: cycle2 25s linear infinite;
}

#slider .animate3 {
   animation: cycle3 25s linear infinite;
}

#slider .animate4 {
   animation: cycle4 25s linear infinite;
}

#slider .animate5 {
   animation: cycle5 25s linear infinite;
}
@keyframes cycle1 {
   0%  { top: 0px; } /* Am Anfang der Slideshow ist das erste Bild sichtbar */
   4%  { top: 0px; } /* Bild steht noch auf der Startposition */
   16% { top: 0px; opacity:1; z-index:0; } /* Von 4% bis 16 % ist das Bild für 3 Sekunden sichtbar */
   20% { top: -325px; opacity: 0; z-index: 0; } /* Von 16% bis 20% = 1 Sekunde für Slide Out */
   21% { top: 325px; opacity: 0; z-index: -1; } /* Zurück auf die Originalposition */
   92% { top: 325px; opacity: 0; z-index: 0; }
   96% { top: 325px; opacity: 0; } /* Von 96% bis 100% = 1 Sekunde für Slide In */
   100%{ top: 0px; opacity: 1; }
}

@keyframes cycle2 {
   0%  { top: 325px; opacity: 0; } /* Originalposition außer Sicht */
   16% { top: 325px; opacity: 0; }/* Beginnt mit der Bewegung */
   20% { top: 0px; opacity: 1; }
   24% { top: 0px; opacity: 1; }  /* Von 20% bis 24% = 1 Sekunde für Slide In */
   36% { top: 0px; opacity: 1; z-index: 0; }   /* Von 24% bis 36 % = Bild für 3 Sekunden sichtbar */
   40% { top: -325px; opacity: 0; z-index: 0; } /* Von 36% bis 40% = 1 Sekunde für Slide Out */
   41% { top: 325px; opacity: 0; z-index: -1; }   /* Zurück auf die Originalposition */
   100%{ top: 325px; opacity: 0; z-index: -1; }
}

@keyframes cycle3 {
   0%  { top: 325px; opacity: 0; }
   36% { top: 325px; opacity: 0; }
   40% { top: 0px; opacity: 1; }
   44% { top: 0px; opacity: 1; }
   56% { top: 0px; opacity: 1; }
   60% { top: -325px; opacity: 0; z-index: 0; }
   61% { top: 325px; opacity: 0; z-index: -1; }
   100%{ top: 325px; opacity: 0; z-index: -1; }
}

@keyframes cycle4 {
   0%  { top: 325px; opacity: 0; }
   56% { top: 325px; opacity: 0; }
   60% { top: 0px; opacity: 1; }
   64% { top: 0px; opacity: 1; }
   76% { top: 0px; opacity: 1; z-index: 0; }
   80% { top: -325px; opacity: 0; z-index: 0; }
   81% { top: 325px; opacity: 0; z-index: -1; }
   100%{ top: 325px; opacity: 0; z-index: -1; }
}

@keyframes cycle5 {
   0%  { top: 325px; opacity: 0; }
   76% { top: 325px; opacity: 0; }
   80% { top: 0px; opacity: 1; }
   84% { top: 0px; opacity: 1; }
   96% { top: 0px; opacity: 1; z-index: 0; }
   100%{ top: -325px; opacity: 0; z-index: 0; }
}

Der Fortschrittsbalken läuft innerhalb der 25 Sekunden 5 mal von links nach rechts – für jedes Bild der Slideshow einmal. In der Sekunde des Wechsels zwischen den Slides ist der Fortschrittsbalken nicht sichtbar.

Progress Bar – Fortschrittsbalken

Der Fortschrittsbalken läuft fünf mal während der 25 Sekunden der Animation – für jedes Bild einmal.

.progress-bar {
   position: relative;
   top: -5px;
   width: 680px;
   height: 5px;
   background: #00f;
   animation: fullexpand 25s ease-out infinite;
}

@keyframes fullexpand {
   /* Anfang: Fortschrittsbalken steht ist nicht sichtbar */
   0%, 20%, 40%, 60%, 80%, 100% { width: 0%; opacity: 0; }

   /* Fortschrittsbalken bereit zum Start */
   4%, 24%, 44%, 64%, 84% { width: 0%; opacity: 0.3; }

   /* Fortschrittsbalken läuft 3 Sekunden an */
   16%, 36%, 56%, 76%, 96% { width: 100%; opacity: 0.7; }

   /* Fortschrittsbalken hat Ende erreicht */
   17%, 37%, 57%, 77%, 97% { width: 100%; opacity: 0.3; }

   /* Fortschrittsbalken wird unsichtbar und beginnt einen neuen Durchlauf */
   18%, 38%, 58%, 78%, 98% { width: 100%; opacity: 0; }
}

Pausieren bei hover

Damit die Slideshow beim Hovern mit der Maus pausiert, sind eigentlich nur wenige Zeilen CSS erforderlich.

/**
#slider li:hover .label {
   left: 0px;
}

#slider:hover li,
#slider:hover .progress-bar {
   animation-play-state: paused;
}
**/

Aber auf den mobilen Geräten gibt es kein Hovern, also muss an dieser Stelle Javascript einspringen. Auch der Text in figcaption class="label" wird während der Pause eingeschoben und sichtbar.

#slider figure.toggle .label {
   left: 0px;
}

#slider figure.toggle,
#slider.toggle .progress-bar {
   animation-play-state: paused;
}
<script>
var slides = document.querySelectorAll("#onframe figure");
for (var i=0; i<slides.length; i++) {
	slides[i].ontouchstart =
	slides[i].onmouseover = function () {
		this.classList.add("toggle");
		document.querySelector("#slider").classList.add("toggle");
		for (var j=0; j<slides.length; j++) {
			slides[j].style.animationPlayState = "paused";
		}
	}
	slides[i].ontouchend =
	slides[i].onmouseout = function () {
		this.classList.remove("toggle");
		document.querySelector("#slider").classList.remove("toggle");
		for (var j=0; j<slides.length; j++) {
			slides[j].style.animationPlayState = "running";
		}
	}
}
</script>

CSS-Animationen vs Animationen mit Javascript

CSS Keyframe-Animationen haben ein großes Potential, aber sie sind nicht so universell wie Animationen mit Javascript. Um mehr oder weniger Bilder in die Slideshow zu setzen, müssen alle Keyframes geändert werden.

04812162024283236404448525660646872768084889296100Slide 1Slide 2Slide 3Slide 4Slide 5ABCA SlideIn 1 sekB Bild steht für 3 sekC SlideOut 1 sek