2014-11-18 7 views
7

Ich versuche, eine 3D-Navbar mit reinem CSS mit Transformationen, Übergängen und Perspektive zu erstellen.3D Navbar, die dreht

Hier ist mein Code:

.navbar-fixed-bottom { 
 
\t background: transparent; 
 
\t } 
 
\t 
 
\t .navbar-perspective { 
 
\t width: 100%; 
 
\t height: 100%; 
 
\t position: relative; 
 
\t -webkit-perspective: 1100px; 
 
\t -moz-perspective: 1100px; 
 
\t perspective: 1100px; 
 
\t -webkit-perspective-origin: 50% 0; 
 
\t -moz-perspective-origin: 50% 0; 
 
\t perspective-origin: 50% 0; 
 
\t } 
 
\t 
 
\t .navbar-perspective > div { 
 
\t margin: 0 auto; 
 
\t position: relative; 
 
\t text-align: justify; 
 
\t -webkit-backface-visibility: hidden; 
 
\t -moz-backface-visibility: hidden; 
 
\t backface-visibility: hidden; 
 
\t -webkit-transition: all 0.5s; 
 
\t -moz-transition: all 0.5s; 
 
\t transition: all 0.5s; 
 
\t height: 50px; 
 
\t font-size:20px; 
 
\t } 
 
\t 
 
\t .navbar-primary { 
 
\t background-color: #cccccc; 
 
\t z-index: 2; 
 
\t -webkit-transform-origin: 0% 100%; 
 
\t -moz-transform-origin: 0% 100%; 
 
\t transform-origin: 0% 100%; 
 
\t } 
 
\t 
 
\t .navbar .navbar-secondary, 
 
\t .navbar .navbar-tertiary { 
 
\t background-color: #bfbfbf; 
 
\t width: 100%; 
 
\t -webkit-transform-origin: 0% 0%; 
 
\t -moz-transform-origin: 0% 0%; 
 
\t transform-origin: 0% 0%; 
 
\t z-index: 1; 
 
\t -webkit-transform: rotateX(-90deg); 
 
\t -moz-transform: rotateX(-90deg); 
 
\t transform: rotateX(-90deg); 
 
\t -webkit-transition: top 0.5s; 
 
\t -moz-transition: top 0.5s; 
 
\t transition: top 0.5s; 
 
\t position: absolute; 
 
\t top: 0; 
 
\t } 
 
\t 
 
\t .navbar .navbar-tertiary { 
 
\t background-color: #b3b3b3; 
 
\t } 
 
\t 
 
\t .navbar-rotate-primary { 
 
\t height: 50px; 
 
\t } 
 
\t 
 
\t .navbar-rotate-primary .navbar-primary { 
 
\t -webkit-transform: translateY(0%) rotateX(0deg); 
 
\t -moz-transform: translateY(0%) rotateX(0deg); 
 
\t transform: translateY(0%) rotateX(0deg); 
 
\t } 
 
\t 
 
\t .navbar-rotate-primary .navbar-secondary, 
 
\t .navbar-rotate-primary .navbar-tertiary { 
 
\t top: 100%; 
 
\t -webkit-transition: -webkit-transform 0.5s; 
 
\t -moz-transition: -moz-transform 0.5s; 
 
\t transition: transform 0.5s; 
 
\t -webkit-transform: rotateX(-90deg); 
 
\t -moz-transform: rotateX(-90deg); 
 
\t transform: rotateX(-90deg); 
 
\t } 
 
\t 
 
\t .navbar-rotate-secondary, 
 
\t .navbar-rotate-tertiary { 
 
\t height: 50px; 
 
\t } 
 
\t 
 
\t .navbar-rotate-secondary .navbar-primary, 
 
\t .navbar-rotate-tertiary .navbar-primary { 
 
\t -webkit-transform: translateY(-100%) rotateX(90deg); 
 
\t -moz-transform: translateY(-100%) rotateX(90deg); 
 
\t transform: translateY(-100%) rotateX(90deg); 
 
\t } 
 
\t 
 
\t .navbar-rotate-secondary .navbar-secondary, 
 
\t .navbar-rotate-tertiary .navbar-secondary { 
 
\t top: 100%; 
 
\t -webkit-transition: -webkit-transform 0.5s; 
 
\t -moz-transition: -moz-transform 0.5s; 
 
\t transition: transform 0.5s; 
 
\t -webkit-transform: rotateX(0deg) translateY(-100%); 
 
\t -moz-transform: rotateX(0deg) translateY(-100%); 
 
\t transform: rotateX(0deg) translateY(-100%); 
 
\t } 
 
\t 
 
\t .navbar-rotate-secondary-fallback .navbar-primary, 
 
\t .navbar-rotate-tertiary-fallback .navbar-primary { 
 
\t display: none; 
 
\t } 
 
\t 
 
\t .navbar-rotate-tertiary .navbar-secondary { 
 
\t -webkit-transform: translateY(-100%) rotateX(90deg); 
 
\t -moz-transform: translateY(-100%) rotateX(90deg); 
 
\t transform: translateY(-100%) rotateX(90deg); 
 
\t } 
 
\t 
 
\t .navbar-rotate-tertiary .navbar-tertiary { 
 
\t top: 100%; 
 
\t -webkit-transition: -webkit-transform 0.5s; 
 
\t -moz-transition: -moz-transform 0.5s; 
 
\t transition: transform 0.5s; 
 
\t -webkit-transform: rotateX(0deg) translateY(-100%); 
 
\t -moz-transform: rotateX(0deg) translateY(-100%); 
 
\t transform: rotateX(0deg) translateY(-100%); 
 
\t }
<html> 
 

 
<head> 
 

 
\t <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 

 
</head> 
 

 
<body> 
 

 
\t <nav id="navigation-bottom" class="navbar navbar-fixed-bottom"> 
 
\t \t <div class="navbar-perspective"> 
 
\t \t \t <div class="navbar-primary"> 
 
\t \t \t \t <a href="javascript:void(0);" onclick="$('#navigation-bottom').attr('class','navbar navbar-fixed-bottom navbar-rotate-secondary')">Rotate To Face 2</a> 
 
\t \t \t </div> 
 
\t \t \t <div class="navbar-secondary"> 
 
\t \t \t \t <a href="javascript:void(0);" onclick="$('#navigation-bottom').attr('class','navbar navbar-fixed-bottom navbar-rotate-tertiary')">Rotate To Face 3</a> 
 
\t \t \t </div> 
 
\t \t \t <div class="navbar-tertiary"> 
 
\t \t \t \t <a href="javascript:void(0);" onclick="$('#navigation-bottom').attr('class','navbar navbar-fixed-bottom navbar-rotate-primary')">Rotate Back To Face 1</a> 
 
\t \t \t </div> 
 
\t \t </div> 
 
\t </nav> 
 

 
</body> 
 

 
</html>

ich die ersten zwei Gesichter haben richtig einen 3D-Effekt mit sich zu drehen, aber das dritte Gesicht sieht nicht richtig aus. Sie werden bemerken, wie Sie sich vom zweiten zum dritten drehen, dass sich das Oberteil nicht richtig dreht und flach aussieht.

Jede Hilfe wird sehr geschätzt.

+0

Hier ist ein JSFiddle: http://jsfiddle.net/wcb6kerq/ – Armin

Antwort

-1

Zunächst einmal vielen Dank an alle, die diese Frage kommentiert und beantwortet haben, vor allem Josh!

Josh, Ihr Beispiel funktioniert perfekt für Browser, die Preserve-3d unterstützen. Das Update, das Sie ohne preserve-3d gepostet haben, erscheint auf IE flach, so dass es für alle Browser noch nicht vollständig war.

Nach drei Tagen von Kopfschmerzen erkannte ich das Problem. Der Ursprung der Seiten wurde nicht korrekt festgelegt. Die Seiten müssen sich um einen Punkt drehen, der halb in der Z-Achse liegt.

Sobald ich den Ursprung aktualisiert haben:

transform-origin: 25px 25px -25px; 

Sobald dies richtig war, alles, was Sie wirklich tun müssen, ist die Drehung des Objekts zu aktualisieren. Keine Notwendigkeit, irgendeine Transformation der X-, Y-, Z-Koordinaten zu verwenden.

Hier ist die Geige und die Lösung für eine 3D-Navigationsleiste, die sich dreht und für alle Browser einschließlich IE10 + funktioniert.

http://jsfiddle.net/tx0emcxe/

+0

Josh, dein Beispiel auf IE hat keine Perspektive. Es ist wie ein 3D-Objekt von vorne betrachten. Wenn sich die Seiten drehen, bewegen sich die Seiten nicht zur Mitte hin und erscheinen somit flach. – Armin

+1

@misterManSam - Sie sind absolut richtig darin und ich bin mir bewusst. Allerdings fühle ich ein wenig verärgert über das Verhalten des Fragestellers und das Beharren, dass meine Antwort irgendwie unvollständig war, sogar in seiner eigenen akzeptierten Antwort. Nicht darum besorgt, dass das Kopfgeld so viel bekommen würde. Um die Community hier nicht zu unterstützen, habe ich meine Kommentare entfernt. Punkt genommen. –

7

Fiddle with a flipping box

Dies ist ganz anders aus, wo Sie begonnen, aber lassen Sie mich meine CSS schreiben und zeigen Ihnen die Geige, und dann werde ich in einer längeren Erklärung bearbeiten, wie und warum das funktioniert:

 

HTML

<section class="container"> 
    <nav id="nav-box" class="show-front"> 
     <div class="front"> 
      <a href="#">Show Bottom</a> 
     </div> 
     <div class="bottom"> 
      <a href="#">Show Back</a></div> 
     <div class="back"> 
      <a href="#">Show Top</a></div> 
     <div class="top"> 
      <a href="#">Show Front</a></div> 
    </nav> 
</section> 

 

CSS

.container { 
    position: relative; 
    perspective: 1000px; 
    transform: scale(0.95); 
} 

#nav-box { 
    width: 100%; 
    height: 50px; 
    position: absolute; 
    transform-origin: center center; 
    transform-style: preserve-3d; 
    transition: transform 0.5s; 
} 

#nav-box div { 
    width: 100%; 
    height: 50px; 
    display: block; 
    position: absolute; 
    transition: background-color 0.5s; 
} 

#nav-box .front { transform: rotateX( 0deg) translateZ(25px); background-color: #ccc; } 
#nav-box .back { transform: rotateX(180deg) translateZ(25px); background-color: #ccc; } 
#nav-box .top { transform: rotateX( 90deg) translateZ(25px); background-color: #ccc; } 
#nav-box .bottom { transform: rotateX(-90deg) translateZ(25px); background-color: #ccc; } 

#nav-box.show-front { transform: rotateY( 0deg); } 
#nav-box.show-front .bottom { background-color: #a0a0a0; } 
#nav-box.show-front .top { background-color: #e0e0e0; } 
#nav-box.show-back { transform: rotateX(-180deg); } 
#nav-box.show-back .bottom { background-color: #e0e0e0; } 
#nav-box.show-back .top { background-color: #a0a0a0; } 
#nav-box.show-top { transform: rotateX( -90deg); } 
#nav-box.show-top .front { background-color: #a0a0a0; } 
#nav-box.show-top .back { background-color: #e0e0e0; } 
#nav-box.show-bottom { transform: rotateX( 90deg); } 
#nav-box.show-bottom .front { background-color: #e0e0e0; } 
#nav-box.show-bottom .back { background-color: #a0a0a0; } 

 

Erklärung der HTML/CSS

unsere Box einrichten

Sie diesen, die falsche Art und Weise begann zu denken ich hasse es zu sagen. Du hast das als "Wie kann ich diese vier Seiten wie eine Box behandeln" anstatt "Wie kann ich eine Box in CSS machen?"

Also lasst uns lernen, wie man eine Kiste macht.

Zuerst erstellen wir einen box Container. Da dies eine Navigationsbox ist, nennen wir sie nav-box. Alle Transformationen, die wir anwenden (außer der Schattierung, auf die wir später noch eingehen werden), werden auf unserer nav-box durchgeführt.

Die Regeln auf unserer nav-box wird bestimmen, wie es sich als ein Objekt verhält. Lassen Sie uns zwei insbesondere diskutieren: transform-origin und transform-style

transform-origin standardmäßig in der Mitte, aber ich wollte es hier herausrufen. Dies wird im Grunde sagen unsere Box: Hey, wir müssen Sie um Ihr absolutes Zentrum schwenken. Wenn wir dies als transform-origin: center bottom' it would look like the box is spinning around its bottom edge. Mitte oben einrichten, würde es sich um seine obere Kante drehen. Ich glaube nicht, dass du das willst.

transform-style muss auf preserve-3d eingestellt werden. Was dies tut ist, den Browser anweisen, nicht mit den Elementen mit transform darunter zu beschäftigen.Andere Optionen sind flat, die den Browser anweist zu ignorieren, dreht sich darunter. Der Grund, warum wir preserve-3d auf unserem nav-box hier setzen möchten, ist sicherzustellen, dass die transforms, die wir auf die Boxseiten angewendet haben, erhalten bleiben, wenn wir transform das Elternteil sind. Ordentliches Zeug, nicht wahr?

Einrichten unserer Seiten

Wir unsere Seiten als Kinder unserer nav-box Einstellung und Positionierung sie nur in der Reihenfolge, dass sie rotateX in Verwendung sein sollte:

  • 0 Rotation für die Vorderseite
  • 180deg für die Rückseite
  • -90deg für den Boden
  • 90deg für die Top-

könnte setzen wir auch eine linke und rechte Seite jetzt mit .left { transform: rotateY(-90deg); } .right { rotateY(90deg); }. Beachten Sie, dass wir für diese beiden Beispiele die Achse Y verwendet haben.

Zweitens, wir setzen einen translateZ Wert von 25px. Was zum Teufel macht das? Es sagt unseren Boxen, dass sie von der Mitte des Elternteils relativ zu ihren jeweiligen Rotationen bewegen müssen. Warum haben wir 25px gewählt? Weil es genau die halbe Höhe jeder unserer Boxen ist. Dies bedeutet, dass es gut mit den Seiten an beiden Kanten bündig wird.

Und dann der spaßige Teil:

Wir beschatten die auf ihre Position basierend Boxen und was auf den Bildschirm gerichtet ist. Die Hintergrundfarben sind relativ zu welcher Seite der Box, die wir zeigen mit show-front, , etc. Die Seite auf der Unterseite wird dunkler, die Seite auf der Oberseite wird heller. Mir hat das einfach gefallen - absolut nicht nötig, um diese Aufgabe zu erfüllen, aber es sieht ein bisschen realistischer aus.

Hoffe, dass hilft!

 


Update für IE

Fiddle Example

Also, gibt es nicht viel ziemlich darüber, sobald wir bekommen durch sie bis zum IE Festsetzung, aber hier ist es. Alle preserve-3d macht die Transformationen für Sie, wenn wir einen Container drehen, anstatt sie zu verflachen. Wenn wir preserve-3d nicht verwenden können, müssen wir basierend auf der Menge der gesamten Rotation berechnen.

Diese Lösung macht das. Ich werde nicht so in der Tiefe auf diesem einem gehen, anstatt, wie viel mehr JavaScript zu markieren dies erfordert und die .rewind Klasse zu markieren:

#nav-box.rewind div { 
    backface-visibility: hidden; 
} 

Weil wir manuell, um diese Lösung Zurückspulen, wir werden müssen verhindern, dass die Neuordnung des z-Index zu den falschen Zeiten angewendet wird. Hier kommt backface-visibility ins Spiel.

Example showing depth in IE

Another example without the need for the rewind class

Hoffnung, die IE für Sie löst.

+0

Vielen Dank für die Antwort, aber das auf IE nicht funktioniert, weil Sie die preserve3d Eigenschaft verwenden. Der Trick besteht darin, diese Eigenschaft NICHT zu verwenden. – Armin

+0

@Armin - Überprüfen Sie die Bearbeitung. Ich habe dir einen IE-fähigen Fix gegeben. –

+0

Besser, funktioniert für IE aber die Perspektive ist flach. – Armin