Als jemand, der gerne CSS-Animationen erstellt, ist perspective eines der mächtigsten Werkzeuge, die ich verwende. Während die perspective-Eigenschaft allein keine 3D-Effekte erzielen kann (da einfache Formen keine Tiefe haben können), können Sie die transform-Eigenschaft verwenden, um Objekte in einem 3D-Raum (mit den X-, Y- und Z-Achsen) zu bewegen und zu drehen und dann perspective zu verwenden, um die Tiefe zu steuern.
In diesem Artikel werde ich versuchen, das Konzept von perspective zu erklären, beginnend mit den Grundlagen, bis hin zu einem vollständig animierten 3D-Würfel.
Die Grundlagen der Perspektive
Wir beginnen mit einem einfachen grünen Quadrat und bewegen es auf allen drei Achsen.
Während das Bewegen des Objekts auf der X- und Y-Achse ziemlich einfach ist, wenn wir es auf der Z-Achse bewegen, wird es so aussehen, als ob das Quadrat gleich bleibt, und das liegt daran, dass die Animation es näher zu uns und dann weiter von uns weg bewegt, wenn sich das Objekt auf der Z-Achse bewegt, aber die Größe (und Position) des Quadrats bleibt gleich. Hier kommt die CSS-Eigenschaft perspective ins Spiel.
Während perspective keinen Einfluss auf das Objekt hat, wenn es sich auf der X- oder Y-Achse bewegt, lässt perspective das Quadrat größer erscheinen, wenn es sich uns nähert, und kleiner, wenn es sich von uns entfernt, wenn sich das Objekt auf der Z-Achse bewegt. Ja, genau wie im „echten“ Leben.
Der gleiche Effekt tritt auf, wenn wir das Objekt drehen
Das Drehen des Quadrats auf der Z-Achse sieht aus wie die normale Drehung, die wir alle kennen und lieben, aber wenn wir das Quadrat auf der X- oder Y-Achse drehen (ohne Perspektive zu verwenden), sieht es nur so aus, als würde das Quadrat kleiner (oder schmaler) werden, anstatt sich zu drehen. Aber wenn wir perspective hinzufügen, können wir sehen, dass die näher gelegene Seite des Quadrats größer und die weiter entfernte Seite kleiner aussieht, wenn sich das Quadrat dreht, und die Drehung sieht wie erwartet aus.
Beachten Sie, dass das Quadrat bei einer Drehung des Objekts um die X- oder Y-Achse um 90° (oder 270°, 450°, 630° usw.) aus dem Blickfeld „verschwindet“. Dies geschieht erneut, weil wir einem Objekt keine Tiefe hinzufügen können, und an dieser Position wird die Breite (oder Höhe) des Quadrats tatsächlich 0 sein.
Der Perspektivwert
Wir müssen die Eigenschaft perspective mit einem Wert festlegen. Dieser Wert legt den Abstand von der Ebene des Objekts fest, oder anders ausgedrückt, die Stärke der Perspektive. Je größer der Wert, desto weiter sind Sie vom Objekt entfernt; je kleiner der Wert, desto deutlicher wird die Perspektive.
Der Perspektivursprung
Die Eigenschaft perspective-origin bestimmt die Position, von der aus Sie ein Objekt „betrachten“. Wenn der Ursprung zentriert ist (was der Standard ist) und das Objekt nach rechts bewegt wird, scheint es, als würden Sie es von links betrachten (und umgekehrt).
Alternativ können Sie das Objekt zentriert lassen und den perspective-origin verschieben. Wenn der Ursprung an die Seite gesetzt wird, ist es, als würden Sie das Objekt von dieser Seite aus „betrachten“. Je größer der Wert, desto weiter seitlich wird es aussehen.
Die Transformation
Während perspective und perspective-origin beide auf dem Elternelement des Objekts gesetzt werden und die Position des Fluchtpunktes bestimmen (d. h. den Abstand von der Objektebene von der Position, von der aus Sie das Objekt „betrachten“), wird die Position und Rotation des Objekts mit der transform-Eigenschaft gesetzt, die auf dem Objekt selbst deklariert ist.
Wenn Sie sich den Code des vorherigen Beispiels ansehen, in dem ich das Quadrat von einer Seite zur anderen bewegt habe, werden Sie sehen, dass ich die Funktion translateX() verwendet habe – was Sinn ergibt, da ich es entlang der X-Achse bewegen wollte. Beachten Sie jedoch, dass es der transform-Eigenschaft zugewiesen ist. Die Funktion ist eine Art Transformation, die direkt auf das zu transformierende Element angewendet wird, aber gemäß den Perspektivregeln des Elternelements funktioniert.
Wir können mehrere Funktionen an die transform-Eigenschaft „ketten“. Bei der Verwendung mehrerer Transformationen sind jedoch drei sehr wichtige Dinge zu beachten
- Beim Drehen eines Objekts wird dessen Koordinatensystem zusammen mit dem Objekt transformiert.
- Beim Verschieben eines Objekts bewegt es sich relativ zu seinem eigenen Koordinatensystem (nicht zu den Koordinaten seines Elternelements).
- Die Reihenfolge, in der diese Werte geschrieben werden, kann (und wird) das Endergebnis ändern.
Um den Effekt zu erzielen, den ich im vorherigen Demo erzielen wollte, musste ich zuerst das Quadrat auf der X-Achse verschieben. Erst dann konnte ich es drehen. Wenn dies andersherum geschehen wäre (erst drehen, dann verschieben), wäre das Ergebnis ein völlig anderes gewesen.
Um zu verdeutlichen, wie wichtig die Reihenfolge der Werte für die transform-Eigenschaft ist, schauen wir uns ein paar kurze Beispiele an. Zuerst eine einfache zweidimensionale (2D) Transformation von zwei Quadraten, die beide die gleichen Transform-Werte haben, aber in unterschiedlicher Reihenfolge deklariert sind
Es ist dasselbe, auch wenn wir die Quadrate auf der Y-Achse drehen
Es sei darauf hingewiesen, dass die Reihenfolge der Werte zwar wichtig ist, wir aber einfach die Werte selbst ändern könnten, um das gewünschte Ergebnis zu erzielen, anstatt die Reihenfolge der Werte zu ändern. Zum Beispiel…
transform: translateX(100px) rotateY(90deg);
…hat denselben Effekt wie
transform: rotateY(90deg) translate<strong>Z(100px);
Das liegt daran, dass wir in der ersten Zeile das Objekt auf der **X-Achse** bewegt haben, bevor wir es gedreht haben, aber in der zweiten Zeile haben wir das Objekt gedreht, seine Koordinaten geändert und es dann auf der **Z-Achse** bewegt. Gleiches Ergebnis, andere Werte.
Schauen wir uns etwas Interessanteres an
Sicher, Quadrate sind eine gute Möglichkeit, das allgemeine Konzept der Perspektive zu erklären, aber wir beginnen wirklich zu sehen, wie Perspektive funktioniert, wenn wir uns mit dreidimensionalen (3D) Formen beschäftigen.
Nutzen wir alles, was wir bisher behandelt haben, um einen 3D-Würfel zu bauen.
Das HTML
Wir erstellen ein .container-Element, das ein .cube-Element umschließt, das wiederum aus sechs Elementen besteht, die die Seiten des Würfels darstellen.
<div class="container">
<div class="cube">
<div class="side front"></div>
<div class="side back"></div>
<div class="side left"></div>
<div class="side right"></div>
<div class="side top"></div>
<div class="side bottom"></div>
</div>
</div>
Das allgemeine CSS
Zuerst fügen wir dem übergeordneten .container-Element eine Perspektive hinzu. Dann stellen wir sicher, dass das .cube-Element 200px Seiten hat und 3D-Transformationen respektiert. Ich füge hier ein paar präsentationsbezogene Stile hinzu, aber die wichtigsten Eigenschaften sind hervorgehoben.
/* The parent container, with perspective */
.container {
width: 400px;
height: 400px;
border: 2px solid white;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
perspective: 800px;
perspective-origin: top right;
}
/* The child element, with 3D tranforms preserved */
.cube {
position: relative;
width: 200px;
height: 200px;
transform-style: preserve-3d;
}
/* The sides of the cube, absolutely positioned */
.side {
position: absolute;
width: 100%;
height: 100%;
opacity: 0.9;
border: 2px solid white;
}
/* Background colors for the cube's sides to help visualize the work */
.front { background-color: #d50000; }
.back { background-color: #aa00ff; }
.left { background-color: #304ffe; }
.right { background-color: #0091ea; }
.top { background-color: #00bfa5; }
.bottom { background-color: #64dd17; }
Die Seiten transformieren
Die Vorderseite ist am einfachsten. Wir bewegen sie um 100px nach vorne
.front {
background-color: #d50000;
transform: translateZ(100px);
}
Wir können die Rückseite des Würfels nach hinten bewegen, indem wir translateZ(-100px) hinzufügen. Eine andere Möglichkeit ist, die Seite um 180 Grad zu drehen und sie dann nach vorne zu bewegen.
.back {
background-color: #aa00ff;
transform: translateZ(-100px);
/* or */
/* transform: rotateY(180deg) translateZ(100px); */
}
Ähnlich wie bei der Rückseite gibt es mehrere Möglichkeiten, die linken und rechten Seiten zu transformieren
.left {
background-color: #304ffe;
transform: rotateY(90deg) translateZ(100px);
/* or */
/* transform: translateX(100px) rotateY(90deg); */
}
.right {
background-color: #0091ea;
transform: rotateY(-90deg) translateZ(100px);
/* or */
/* transform: translateX(-100px) rotateY(90deg); */
}
Die Ober- und Unterseite sind etwas anders. Anstatt sie auf der Y-Achse zu drehen, müssen wir sie auf der X-Achse drehen. Auch dies kann auf verschiedene Arten geschehen
.top {
background-color: #00Bfa5;
transform: rotateX(90deg) translateZ(100px);
/* or */
/* transform: translateY(-100px) rotateX(90deg); */
}
.bottom {
background-color: #64dd17;
transform: rotateX(-90deg) translateZ(100px);
/* or */
/* transform: translateY(100px) rotateX(90deg); */
}
Dies ergibt einen 3D-Würfel!
Spielen Sie ruhig mit den verschiedenen Optionen für perspective und perspective-origin, um zu sehen, wie sie sich auf den Würfel auswirken.
Sprechen wir über transform-style
Wir werden unserem Würfel eine schicke Animation hinzufügen, aber sprechen wir zuerst über die Eigenschaft transform-style. Ich habe sie früher im allgemeinen CSS hinzugefügt, aber nicht wirklich erklärt, was sie ist oder was sie tut.
Die transform-style-Eigenschaft hat zwei Werte:
flat(Standard)preserve-3d
Wenn wir die Eigenschaft auf preserve-3d setzen, tut sie zwei wichtige Dinge:
- Sie weist die Seiten des Würfels (die Kindelemente) an, im selben 3D-Raum wie der Würfel positioniert zu werden. Wenn sie nicht auf
preserve-3dgesetzt ist, ist der Standardwertflat, und die Seiten werden in der Ebene des Würfels abgeflacht.preserve-3d„kopiert“ die Würfelperspektive auf seine Kinder (die Seiten) und erlaubt uns, nur den Würfel zu drehen, sodass wir nicht jede Seite einzeln animieren müssen. - Sie zeigt die Kindelemente gemäß ihrer *Position* im 3D-Raum an, unabhängig von ihrem *Platz* im DOM.
Es gibt drei Quadrate in diesem Beispiel – grün, rot und blau. Das grüne Quadrat hat einen translateZ-Wert von 100px, was bedeutet, dass es vor den anderen Quadraten liegt. Das blaue Quadrat hat einen translateZ von -100px, was bedeutet, dass es hinter den anderen Quadraten liegt.
Aber im DOM ist die Reihenfolge der Quadrate: grün, rot, blau. Daher wird das blaue Quadrat oben erscheinen, wenn transform-style auf flat gesetzt ist (oder gar nicht gesetzt ist), und das grüne Quadrat wird hinten liegen, weil das die Reihenfolge des DOM ist. Aber wenn wir transform-style auf preserve-3d setzen, wird es entsprechend seiner Position im 3D-Raum gerendert. Als Ergebnis wird das grüne Quadrat vorne und das blaue Quadrat hinten sein.
Animation
Jetzt animieren wir den Würfel! Und um die Dinge interessanter zu gestalten, fügen wir die Animation zu allen drei Achsen hinzu. Zuerst fügen wir die animation-Eigenschaft zum .cube hinzu. Sie wird noch nichts tun, da wir die Animations-Keyframes noch nicht definiert haben, aber sie ist vorhanden, wenn wir es tun.
animation: cubeRotate 10s linear infinite;
Nun die Keyframes. Wir werden den Würfel im Grunde entlang jeder Achse drehen, sodass er sich im Raum zu drehen scheint.
@keyframes cubeRotate {
from { transform: rotateY(0deg) rotateX(720deg) rotateZ(0deg); }
to { transform: rotateY(360deg) rotateX(0deg) rotateZ(360deg); }
}
Die perspective-Eigenschaft ist es, die der Animation wirklich Tiefe verleiht, als würden wir den Würfel sich nach links und rechts sowie nach vorne und hinten drehen sehen.
Aber bisher war der Wert der perspective-Eigenschaft konstant, ebenso wie die perspective-origin. Sehen wir uns an, wie sich die Änderung dieser Werte auf das Erscheinungsbild des Würfels auswirkt.
Ich habe drei Schieberegler zu diesem Beispiel hinzugefügt, um zu sehen, wie verschiedene Werte die Perspektive des Würfels beeinflussen.
- Der linke Schieberegler setzt den Wert der
perspective-Eigenschaft. Denken Sie daran, dieser Wert setzt den Abstand von der Objektebene, also je kleiner der Wert ist, desto deutlicher ist der Perspektiveffekt. - Die beiden anderen Schieberegler beziehen sich auf die
perspective-origin-Eigenschaft. Der rechte Schieberegler setzt den Ursprung auf der vertikalen Achse von oben nach unten, und der untere Schieberegler setzt den Ursprung auf der horizontalen Achse von rechts nach links.
Beachten Sie, dass diese Änderungen während der laufenden Animation weniger auffällig sein können, da sich der Würfel selbst dreht, aber Sie können die Animation leicht ausschalten, indem Sie auf die Schaltfläche „Animation ausführen“ klicken.
Spielen Sie mit diesen Werten herum und finden Sie heraus, wie sie das Aussehen des Würfels beeinflussen. Es gibt keinen „richtigen“ Wert, und diese Werte variieren von Projekt zu Projekt, da sie von der Animation, der Größe des Objekts und dem gewünschten Effekt abhängen.
Was kommt als Nächstes?
Nachdem Sie nun die Grundlagen der perspective-Eigenschaft in CSS beherrschen, können Sie Ihre Vorstellungskraft und Kreativität nutzen, um 3D-Objekte in Ihren eigenen Projekten zu erstellen und Ihren Schaltflächen, Menüs, Eingabefeldern und allem anderen, was Sie „zum Leben erwecken“ möchten, Tiefe und Interesse zu verleihen.
In der Zwischenzeit können Sie Ihre Fähigkeiten üben und verbessern, indem Sie versuchen, komplexe Strukturen und perspektivbasierte Animationen wie diese, diese, diese oder sogar diese zu erstellen.

Ich hoffe, Sie haben diesen Artikel genossen und dabei etwas Neues gelernt! Hinterlassen Sie gerne einen Kommentar, um mir mitzuteilen, was Sie denken, oder schreiben Sie mir eine Nachricht auf Twitter, wenn Sie Fragen zu Perspektive oder einem anderen Thema in diesem Artikel haben.
Wow! Danke. Ich hatte Perspektive bisher vermieden.
Danke dafür, ich habe versucht, meinen Animationen und Logos 3D-Effekte zu verleihen. Bis heute wusste ich nicht, wie man die „translateZ“-Eigenschaft benutzt, noch kannte ich die Macht der „Perspektive“ (des CSS-Lebens).
Das ist großartig. Tolle Ausarbeitung, hilft wirklich, es gründlich zu verstehen, damit wir es auf unsere Projekte anwenden können. Danke!
Danke Amit,
Das hat mir einen klareren Einblick in die Perspektive gegeben. Ich habe Perspektive aus einem Artikel kennengelernt, sie aber nicht wirklich verstanden, aber ich habe sie trotzdem richtig benutzt. Lasst mich meinen Schreibtisch wieder besuchen. Viele Projekte kommen mir in den Sinn. Einige, die ich vielleicht nicht realisieren kann. LOL!
Tolle Arbeit! Liebe es!
Das wäre großartig, wenn die Anwendungsreihenfolge für zusammengesetzte Transformationen richtig wäre. Laut MDN (Hervorhebung von mir)
Das Beispiel
rotate(30deg) translateX(140px)lässt sich am besten visualisieren, indem zuerst die Box entlang der x-Achse verschoben und dann um 30 Grad gedreht wird. Jede zusammengesetzte Transformation hat eine äquivalente Transformationsmatrix. Diese werden von links nach rechts multipliziert.Ich schätze die Mühe, aber viele der Beispiele sind so fehlerhaft, dass ich nicht wirklich erkennen kann, was erklärt wird (Firefox 80/Mac).
Großartig!! Tolle Art, CSS-Perspektive zu lernen.
Mark, werde das hier versuchen
Eines der wichtigsten Dinge bei CSS-Animationen
Das hat mein Wissen wirklich bereichert. Ich bin so dankbar.
Toller Artikel, ich habe viel gelernt.
Interessante Wahl bei Ihren Regeln für die
transform-Eigenschaft. Regel 1 besagt: „Beim Drehen eines Objekts wird dessen Koordinatensystem zusammen mit dem Objekt transformiert.“ Sie kombinieren das mit der Idee, dass die Transform-Funktionen von links nach rechts angewendet werden.Die semi-offizielle Dokumentation auf MDN erzählt eine andere Geschichte: Die Transform-Funktionen werden von rechts nach links angewendet, und die X-Y-Z-Achsen rotieren oder bewegen sich nicht mit dem Objekt.
Mathematisch sind die beiden Ansätze äquivalent. Ich würde sagen, dass die Beibehaltung der unveränderten Achsen den Vorteil hat, dass man die Achsen nicht im Kopf drehen muss. Wenn die erste Transform-Funktion z. B.
rotateZ(90deg)ist, muss man sich merken, dass die X-Achse jetzt nach unten zeigt und die Y-Achse horizontal geworden ist. Das Lesen von rechts nach links stellt keine solchen Anforderungen an den Verstand.Um diese Anmerkungen nach etwas mehr Überlegung zu ergänzen: Das Bild der „transformierten Achsen“ wird besonders problematisch, wenn die Transform-Funktion
scaleist. Der Programmierer ist dann gezwungen, sich Achsen vorzustellen, die für dieselbe Einheit unterschiedliche Längen haben.Stellen Sie sich zum Beispiel ein Element von 100px * 100px vor. Vor jeder Transformation befindet sich sein linker Rand bei X=-50px und sein rechter Rand bei X=50px. Jetzt transformieren wir es
In MDNs Rechts-nach-Links-Bild wird es zuerst um 50 Pixel nach rechts verschoben, sodass seine Ränder bei X=0 und X=100px liegen; dann werden die X-Koordinaten verdoppelt, sodass die Ränder bei X=0 und X=200px liegen. Dieses Ergebnis ist das, was wir tatsächlich sehen.
Nach Ihrem Bild werden die Koordinaten zuerst verdoppelt, um X=-100px und X=100px zu sein, und dann... das Objekt wird um 50 Pixel nach rechts verschoben, *die nun 100 Pixel breit sind, weil die Skalierung der X-Achse ebenfalls verdoppelt wurde.* Während also auf der Y- und Z-Achse 50 Pixel 50 Pixel sind, sind auf der X-Achse 50 Pixel der Abstand, der tatsächlich 100 Pixel beträgt.
Das Ergebnis ist wieder das richtige, aber das verlangt dem Vorstellungsvermögen des Programmierers viel ab.
Dieser Artikel ist beeindruckend. Danke!