Webdesign - 3D Slider mit CSS3-Transitionen und Keyframe-Animationen

  1. Zum Inhalt springen

webdesign
klamonfra
Klaus Franz


Kleines Cottage
Kleines Cottage mit Reetdach
Weiler Runch
Der Weiler Runch
Gerfalke
Gerfalke
Wollkopfgeier
Wollkopfgeier
Lobiser-Schupfen
Lobiser-Schupfen

Photos © Monika & Klaus Franz

Wie realisiert man einen 3D Slider ohne JavaScript?

07Nov2014

3D Slider mit CSS3-Transitionen und Keyframe-Animationen.


Die 3D Slider auf dieser Seite sind eine Weiterentwicklung der zweidimensionalen Cycle Slider. Auch hierzu gibt es im Internet bereits viele Beispiele, die aber fast alle mit JavaScript (objektorientierte Programmiersprache) und jQuery-Plugins realisiert wurden.
Der erste 3D-Slider soll dabei einer Bilderbox oder einem Würfel gleichen.

Der dreidimensionale Würfel-Slider

Durch das Drehen der Bilder wie auf einem Würfel kann man ebenfalls sehr ausgefallen sein Portfolio präsentieren und es sind lediglich ein paar Anpassungen im CSS3 (Cascading Style Sheet) notwendig um dem Ganzen ein entsprechendes Aussehen zu geben.
Der Aufbau des HTML5 (HyperText Markup Language)-Gerüsts ist identisch dem Cycle Slider, nur dass ich hier auf den Fortschrittsbalken verzichtet habe.

<div id="stapel">
    <figure>
        <img src="bilder500/Cottage.jpg" width="500"
             height="333" alt="Kleines Cottage">
        <figcaption>Kleines Cottage mit Reetdach</figcaption>
    </figure>
    <figure>
        <img src="bilder500/Runch.jpg" width="500"
             height="333" alt="Weiler Runch">
        <figcaption>Der Weiler Runch</figcaption>
    </figure>
    <figure>
        <img src="bilder500/Gerfalke.jpg" width="500"
             height="333" alt="Gerfalke">
        <figcaption>Gerfalke</figcaption>
    </figure>
    <figure>
        <img src="bilder500/Wollkopfgeier.jpg" width="500"
             height="333" alt="Wollkopfgeier">
        <figcaption>Wollkopfgeier</figcaption>
    </figure>
    <figure>
        <img src="bilder500/Lobiser-Schupfen.jpg" width="500"
             height="333" alt="Lobiser-Schupfen">
        <figcaption>Lobiser-Schupfen</figcaption>
    </figure>
    <div class="pause"></div>
</div>

Die Besonderheit ist nun die 3D-Transform!
Die Eigenschaft "perspective" fügt CSS3 (Cascading Style Sheet)-Transformationen die Illusion von Tiefe und Räumlichkeit hinzu. Ein Wert von 2000 Pixel entspricht einer Teleperspektive und je kleiner der Wert desto mehr geht es Richtung Weitwinkelperspektive. Außerdem muss der Wert im übergeordneten Element des zu transformierenden Elements angegeben werden. Und damit alle verschachtelten Elemente auch dreidimensional dargestellt werden, benötigt man noch die Eigenschaft "transform-style: preserve-3d".
Bei diesem Beispiel werden der Schatten und der Rahmen direkt den Bildern zugeordnet.
Unten sind sämtliche Anweisungen im CSS3 (Cascading Style Sheet) für das Beispiel aufgeführt.

#stapel {
    position: relative;
    height: 23em;
    width: 31.25em;
    margin: 6em auto 0;
    cursor: pointer;
    perspective: 1500px;
    transform-style: preserve-3d;
}

#stapel img {
    border: 5px solid #eee;
    box-shadow: 1px 1px 5px 2px #777;
}

#stapel figure {
    position: absolute;
    margin: 0;
    height: 20.8em;
    width: 31.25em;
    opacity: 0;
}

#stapel figcaption {
    position: relative;
    overflow: hidden;
    color: #fff;
    font: 1.1em/2.5 Verdana;
    letter-spacing: .1em;
    text-align: center;
    max-width: 380px;
    margin: 0 auto;
    bottom: 43px;
    opacity: 0;
    transition: 1s;
}

#stapel figcaption:after {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: .1em;
    background: #fff;
    content: '';
    transition: transform .5s;
    transform: translate3d(-100%,0,0);
}

#stapel:hover figcaption,
#stapel:hover figcaption:after {
    opacity: 1;
    transform: translate3d(0,0,0);
}

#stapel figure:nth-of-type(1) {
    animation: bild 30s ease-in-out infinite;
}

#stapel figure:nth-of-type(2) {
    animation: bild 30s 6s ease-in-out infinite;
}

#stapel figure:nth-of-type(3) {
    animation: bild 30s 12s ease-in-out infinite;
}

#stapel figure:nth-of-type(4) {
    animation: bild 30s 18s ease-in-out infinite;
}

#stapel figure:nth-of-type(5) {
    animation: bild 30s 24s ease-in-out infinite;
}

@keyframes bild {
     6.66%       {opacity:1; z-index:3;
                  transform:rotateY(0deg) translateZ(253px);}
    20%          {opacity:1; z-index:4;
                  transform:rotateY(0deg) translateZ(253px);}
    26.66%       {opacity:1; z-index:2;
                  transform:rotateY(-90deg) translateZ(250px);}
    26.67%, 100% {opacity:0; z-index:1;
                  transform:rotateY(90deg) translateZ(250px);}
    0%           {opacity:1; z-index:1;
                  transform:rotateY(90deg) translateZ(261px);}
}

Bei der "@keyframes-Regel" wird dann die Drehung der Bilder festgelegt, mit "transform: translateZ(250px)" wird das Bild in der z-Achse perspektivisch vergrößert und mit dem "z-index" wird bestimmt zu welchem Zeitpunkt die Bilder in den Vordergrund oder in den Hintergrund treten. Für die zeitliche Funktion wähle ich "animation: ease-in-out" damit der Würfel immer wieder für kurze Zeit anhält.
Und schon erhält man diese tolle dreidimensionale Bilderbox!


Der dreidimensionale vertikale Würfel-Slider

Damit sich der 3D-Würfel-Slider in der Vertikalen dreht, wird lediglich die Angabe "transform: rotateY" durch "transform: rotateX" ersetzt. Die optimalen Größenangaben bei "transform: translateZ( )" müssen durch Testen ermittelt werden.

@keyframes bildw {
     6.66%       {opacity:1; z-index:3;
                  transform:rotateX(0deg) translateZ(170px);}
    20%          {opacity:1; z-index:4;
                  transform:rotateX(0deg) translateZ(175px);}
    26.66%       {opacity:1; z-index:2;
                  transform:rotateX(-90deg) translateZ(175px);}
    26.67%, 100% {opacity:0; z-index:1;
                  transform:rotateX(90deg) translateZ(175px);}
    0%           {opacity:1; z-index:1;
                  transform:rotateX(90deg) translateZ(165px);}
}
Kleines Cottage
Kleines Cottage mit Reetdach
Weiler Runch
Der Weiler Runch
Gerfalke
Gerfalke
Wollkopfgeier
Wollkopfgeier
Lobiser-Schupfen
Lobiser-Schupfen

Der dreidimensionale Karussell-Slider

Der nächste 3D-Slider soll die Bilder wie auf einem Karussell einblenden.
Der Aufbau des HTML5 (HyperText Markup Language)-Gerüsts wird wieder genau wie beim ersten Beispiel erstellt. Dieses Mal werden allerdings 9 Bilder animiert. Die Größe der Bilder ist auf Grund des Platzmangels auf einer Breite von 210 Pixel beschränkt.

Beim CSS3 (Cascading Style Sheet) wende ich für dieses Beispiel wieder nur eine "@keyframes-Regel" an, mit dem Nachteil, dass die Bilder in der ersten Schleife erst nacheinander eingeblendet werden. Und erst nach Durchlauf des ersten Zyklus von 36 Sekunden läuft das "3D-Karussell" komplett rund, aber dafür sieht man sehr gut den Aufbau des Sliders. Bei der zeitlichen Funktion wähle ich, im Gegensatz zum Würfel, "animation: linear" damit das Karussell nicht zwischendurch stoppt.

Kleines Cottage
Kleines Cottage mit Reetdach
Weiler Runch
Der Weiler Runch
Gerfalke
Gerfalke
Wollkopfgeier
Wollkopfgeier
Lobiser-Schupfen
Lobiser-Schupfen
Herbstfarben
Herbstfarben
Strand bei Portsalon
Strand bei Portsalon
Kornfeld
Kornfeld
Blume
Blume

Das CSS3 (Cascading Style Sheet) ist für diesen 3D-Slider folgendermaßen aufgebaut:

#stapel1 {
    position: relative;
    height: 20em;
    width: 44.5em;
    margin: 1em -1em;
    cursor: pointer;
    perspective: 1000px;
    transform-style: preserve-3d;
    background: #aaa;
    border: 5px solid #eee;
    box-shadow: 1px 1px 5px 2px #777;
}

#stapel1 img {
    border: 5px solid #eee;
    box-shadow: 1px 1px 5px 2px #777;
}

#stapel1 figure {
    position: absolute;
    margin: 0;
    width: 13.75em;
    height: 9.375em;
    left: 15.4em;
    top: 5em;
    opacity: 0;
}

#stapel1 figcaption {
    position: absolute;
    color: #444;
    font: .7em/1.25 Verdana;
    text-align: center;
    background: rgba(255, 255, 255, .7);
    border: 1px solid #fff;
    box-shadow: 1px 1px 5px 2px #777;
    width: 18.5em;
    height: 1.25em;
    top: 155px;
    left: 5px;
    opacity: 0;
    transition: 1s;
}

#stapel1:hover figcaption {
    opacity: 1;
}

#stapel1 figure:nth-of-type(1) {
    animation: bild1 36s linear infinite;
}

#stapel1 figure:nth-of-type(2) {
    animation: bild1 36s 4s linear infinite;
}

#stapel1 figure:nth-of-type(3) {
    animation: bild1 36s 8s linear infinite;
}

#stapel1 figure:nth-of-type(4) {
    animation: bild1 36s 12s linear infinite;
}

#stapel1 figure:nth-of-type(5) {
    animation: bild1 36s 16s linear infinite;
}

#stapel1 figure:nth-of-type(6) {
    animation: bild1 36s 20s linear infinite;
}

#stapel1 figure:nth-of-type(7) {
    animation: bild1 36s 24s linear infinite;
}

#stapel1 figure:nth-of-type(8) {
    animation: bild1 36s 28s linear infinite;
}

#stapel1 figure:nth-of-type(9) {
    animation: bild1 36s 32s linear infinite;
}

@keyframes bild1 {
      0%    {opacity:  1; z-index:5;
             transform:rotateY(0deg) translateZ(315px);}
     11.11% {opacity: .9; z-index:4;
             transform:rotateY(40deg) translateZ(315px);}
     22.22% {opacity: .7; z-index:3;
             transform:rotateY(80deg) translateZ(315px);}
     33.33% {opacity: .5; z-index:2;
             transform:rotateY(120deg) translateZ(315px);}
     44.44% {opacity: .3; z-index:1;
             transform:rotateY(160deg) translateZ(315px);}
     55.56% {opacity: .3; z-index:1;
             transform:rotateY(200deg) translateZ(315px);}
     66.67% {opacity: .5; z-index:2;
             transform:rotateY(240deg) translateZ(315px);}
     77.78% {opacity: .7; z-index:3;
             transform:rotateY(280deg) translateZ(315px);}
     88.89% {opacity: .9; z-index:4;
             transform:rotateY(320deg) translateZ(315px);}
    100%    {opacity:  1; z-index:5;
             transform:rotateY(360deg) translateZ(315px);}
}

#stapel1:hover figure {
    animation-play-state: paused;
}

Auf die Angabe von "transform: rotateY" und "transform: translateZ" kann man bei den Prozentsätzen zwischen 11,11% und 88,89% verzichten, da sich die Werte bei "transform: rotateY" gleichmäßig von 0 deg bis 360 deg erhöhen und der Wert bei "transform: translateZ" immer gleich bleibt. Auch auf die Angabe von "opacity" könnte man verzichten wenn sich die Deckkraft gleichmäßig verändern soll. Dafür müsste man lediglich bei 50% eine Deckkraft von 0,3 einstellen.
Die Definition des "z-index" ist allerdings wegen der Anzeige der Bilder im Vorder- und Hintergrund bei jeder Prozentangabe notwendig.

Für die Berechnung der Verschiebung in die Tiefe "transform: translateZ" geht man wie folgt vor.
Die Breite jedes Bildes inklusive Rand beträgt 220 Pixel und jedes Bild ist dabei um 40 Grad zum nächsten Bild auf dem Karussell gedreht. Wenn man das erhaltene Dreieck halbiert, erhält man ein rechtwinkliges Dreieck und kann mit dem Tangenssatz die Tiefe "transform: translateZ" berechnen.

Erklärung der transform: rotateY

Berechnung der wichtigsten Größen, Zeiten und Winkel im Überblick.
In Klammern stehen die Werte für diesen dreidimensionalen Karussell-Slider:

A:           Anzahl der Bilder (9 Bilder)

D:           Dauer für Wechsel zum nächsten Bild (4 Sekunden)

G = D * A:   Gesamtdauer der Animation (36 Sekunden)

S = G / A:   Staffelung der Startzeiten (4 Sekunden)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

V:           Vollwinkel eines Kreises beträgt 360°

Y = V / A    Erhöhung von "transform: rotateY" (40° oder 40deg)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

B:           Breite eines Bildes (210 Pixel)

H:           Höhe eines Bildes (140 Pixel)

R:           Rand um ein Bild (5Pixel)
             #stapel1 img {border: 5px solid #eee}

w:           Breite eines Bildes inklusive Rand (220 Pixel oder 13,75em)
             #stapel1 figure {width: 13,75em}

h:           Höhe eines Bildes inklusive Rand (150 Pixel oder 9,375em)
             #stapel1 figure {height: 9.375em}

Tangenssatz bei einem rechtwinkligen Dreieck:
tan α = Gegenkathete / Ankathete
tan(Y / 2) = (w / 2) / Z
Z          = (w / 2) / tan(Y / 2) = 110Pixel / tan(20°) = 302 Pixel

Eingestellt habe ich für die Tiefe "transform: translateZ" dann 315 Pixel und erhalte dadurch von einem zum nächsten Bild noch einen kleinen Abstand von knapp 4,6 Pixel.


Der 3D-Karussell-Slider im Uhrzeigersinn

Damit sich der 3D-Karussell-Slider anders herum dreht, wird lediglich die "@keyframes-Regel" für 0% und 100% getauscht.

@keyframes bild2 {
      0%    {opacity:  1; z-index:5;
             transform:rotateY(360deg) translateZ(315px);}
     ...
    100%    {opacity:  1; z-index:5;
             transform:rotateY(0deg) translateZ(315px);}
}
Kleines Cottage
Kleines Cottage mit Reetdach
Weiler Runch
Der Weiler Runch
Gerfalke
Gerfalke
Wollkopfgeier
Wollkopfgeier
Lobiser-Schupfen
Lobiser-Schupfen
Herbstfarben
Herbstfarben
Strand bei Portsalon
Strand bei Portsalon
Kornfeld
Kornfeld
Blume
Blume

Der 3D-Karussell-Slider mit versetzten Bildern

Bei diesem 3D-Karussell-Slider sind die Bilder etwas versetzt.
Hierfür kommt zusätzlich zu der Tiefe "transform: translateZ" noch die Höhe mit "transform: translateY" ins Spiel, und das kann man dann mit "transform: translate3d(x,y,z)" zusammenfassen. Die Deckkraft wird zu jedem Zeitpunkt auf 100% gesetzt.

@keyframes bild3 {
      0%    {opacity: 1; z-index:5;
             transform:rotateY(360deg) translate3d(0,150px,315px);}
     11.11% {z-index:4;
             transform:rotateY(320deg) translate3d(0,120px,315px);}
     22.22% {z-index:3;
             transform:rotateY(280deg) translate3d(0,90px,315px);}
     33.33% {z-index:2;
             transform:rotateY(240deg) translate3d(0,60px,315px);}
     44.44% {z-index:1;
             transform:rotateY(200deg) translate3d(0,30px,315px);}
     55.56% {z-index:1;
             transform:rotateY(160deg) translate3d(0,30px,315px);}
     66.67% {z-index:2;
             transform:rotateY(120deg) translate3d(0,60px,315px);}
     77.78% {z-index:3;
             transform:rotateY(80deg) translate3d(0,90px,315px);}
     88.89% {z-index:4;
             transform:rotateY(40deg) translate3d(0,120px,315px);}
    100%    {opacity: 1; z-index:5;
             transform:rotateY(0deg) translate3d(0,150px,315px);}
}
Kleines Cottage
Kleines Cottage mit Reetdach
Weiler Runch
Der Weiler Runch
Gerfalke
Gerfalke
Wollkopfgeier
Wollkopfgeier
Lobiser-Schupfen
Lobiser-Schupfen
Herbstfarben
Herbstfarben
Strand bei Portsalon
Strand bei Portsalon
Kornfeld
Kornfeld
Blume
Blume

Der 3D-Karussell-Slider mit schrägen Bildern

Noch besser wirken die versetzten Bilder wenn sie gleichzeitig auch schräg gestellt werden.
Hierfür benutze ich das Objekt "transform: skewY" zum Neigen der Bilder in der Y-Achse. Um die Bilder dann vernünftig zu setzen, muss man die optimalen Größenangaben bei "transform: skewY" und "transform: translate3d(x,y,z)" durch Testen ermitteln.

@keyframes bild4 {
      0%    {opacity: 1; z-index:5; transform:rotateY(360deg)
             skewY(0deg) translate3d(0,128px,315px);}
     11.11% {z-index:4; transform:rotateY(320deg)
             skewY(13deg) translate3d(0,100px,315px);}
     22.22% {z-index:3; transform:rotateY(280deg)
             skewY(12deg) translate3d(0,50px,315px);}
     33.33% {z-index:2; transform:rotateY(240deg)
             skewY(12deg) translate3d(0,0,315px);}
     44.44% {z-index:1; transform:rotateY(200deg)
             skewY(7deg) translate3d(0,-40px,315px);}
     55.56% {z-index:1; transform:rotateY(160deg)
             skewY(-7deg) translate3d(0,-40px,315px);}
     66.67% {z-index:2; transform:rotateY(120deg)
             skewY(-12deg) translate3d(0,0,315px);}
     77.78% {z-index:3; transform:rotateY(80deg)
             skewY(-12deg) translate3d(0,50px,315px);}
     88.89% {z-index:4; transform:rotateY(40deg)
             skewY(-13deg) translate3d(0,100px,315px);}
    100%    {opacity: 1; z-index:5; transform:rotateY(0deg)
             skewY(0deg) translate3d(0,128px,315px);}
}
Kleines Cottage
Kleines Cottage mit Reetdach
Weiler Runch
Der Weiler Runch
Gerfalke
Gerfalke
Wollkopfgeier
Wollkopfgeier
Lobiser-Schupfen
Lobiser-Schupfen
Herbstfarben
Herbstfarben
Strand bei Portsalon
Strand bei Portsalon
Kornfeld
Kornfeld
Blume
Blume

Dieser dreidimensionale Karussell-Slider sieht jetzt richtig schick aus!


Der 3D-Karussell-Slider in der Vertikalen

Oder wie wäre es mit einem 3D-Karussell-Slider der in der Vertikalen abläuft.
Hierbei wird natürlich für die Größenbestimmung von "transform: translateZ" als Basis die Höhe der Bilder inklusive Rand von 150 Pixel genommen, erhält einen ausgerechneten Wert von 206 Pixel und, weil ich wieder einen Abstand zwischen den Bildern haben möchte, stelle ich den Wert auf 215 Pixel ein. Die Angabe "transform: rotateY" wird durch "transform: rotateX" ersetzt und schon hat man einen weiteren optisch interessanten 3D-Slider!

@keyframes bild5 {
      0%    {opacity:  1; z-index:5;
             transform:rotateX(360deg) translateZ(215px);}
     11.11% {opacity: .9; z-index:4;}
     22.22% {opacity: .7; z-index:3;}
     33.33% {opacity: .5; z-index:2;}
     44.44% {opacity: .3; z-index:1;}
     55.56% {opacity: .3; z-index:1;}
     66.67% {opacity: .5; z-index:2;}
     77.78% {opacity: .7; z-index:3;}
     88.89% {opacity: .9; z-index:4;}
    100%    {opacity:  1; z-index:5;
             transform:rotateX(0deg) translateZ(215px);}
}
Kleines Cottage
Weiler Runch
Gerfalke
Wollkopfgeier
Lobiser-Schupfen
Herbstfarben
Strand bei Portsalon
Kornfeld
Blume

Der 3D-Karussell-Slider als Halbbogen

Eine schöne Variante ist es, wenn man nur den Hintergrund des Karussells erscheinen lässt.
Der Trick bei der Sache ist aber, dass die Bilder eigentlich spiegelverkehrt dargestellt würden. Aber mit der zusätzlichen Angabe "transform: rotateY(180deg)" werden sowohl die Bilder als auch die Texte vorab gedreht und schon passt es wieder.

#stapel6 img,
#stapel5 figcaption {
    transform: rotateY(180deg);
}

@keyframes bild6 {
      0%    {opacity: 0; z-index:2;
             transform:rotateY(280deg) translateZ(315px);}
     11.11% {opacity: 1; z-index:2;}
     44.44% {opacity: 1; z-index:2;}
     55.56% {opacity: 0; z-index:1;}
     77.78% {opacity: 0; z-index:1;
             transform:rotateY(0deg) translateZ(315px);}
    100%    {opacity: 0; z-index:1;
             transform:rotateY(320deg) translateZ(315px);}
}
Kleines Cottage
Kleines Cottage mit Reetdach
Weiler Runch
Der Weiler Runch
Gerfalke
Gerfalke
Wollkopfgeier
Wollkopfgeier
Lobiser-Schupfen
Lobiser-Schupfen
Herbstfarben
Herbstfarben
Strand bei Portsalon
Strand bei Portsalon
Kornfeld
Kornfeld
Blume
Blume

Der 3D-Karussell-Slider läuft im Kreis

Ganz verrückt ist dann der letzte 3D-Karussell-Slider. Hierbei wird die Angabe "transform: rotateY" durch "transform: rotate3d(0,1,1,360deg)" ersetzt und die Deckkraft konstant auf 100% gesetzt.
Dieser Effekt funktioniert allerdings nicht mit dem Internet Explorer.

@keyframes bild7 {
      0%    {opacity:  1; z-index:5;
             transform:rotate3d(0,1,1,360deg) translate3d(0,0,315px);}
     11.11% {z-index:4;}
     22.22% {z-index:3;}
     33.33% {z-index:2;}
     44.44% {z-index:1;}
     55.56% {z-index:1;}
     66.67% {z-index:2;}
     77.78% {z-index:3;}
     88.89% {z-index:4;}
    100%    {opacity:  1; z-index:5;
             transform:rotate3d(0,1,1,0deg) translate3d(0,0,315px);}
}
Kleines Cottage
Weiler Runch
Gerfalke
Wollkopfgeier
Lobiser-Schupfen
Herbstfarben
Strand bei Portsalon
Kornfeld
Blume

Wie man sieht sind mit ein wenig Fantasie viele verschiedene 3D-Karussell-Slider, auch ohne Einsatz von JavaScript (objektorientierte Programmiersprache), möglich.

Zum Seitenanfang springen Λ