CSS 3D Transforms verstehen (CSS 3D – 1)

Bevel, Dropshadow, Gloss und Glow sind Designers gestalterische Schokoriegel - alle wissen, dass man sie tunlichst meiden sollte, aber von Zeit zu Zeit können wir halt nicht wiederstehen. Die größte Kalorienbombe im Sortiment ist dabei 3-D. Ahhh 3D - was wäre damit alles möglich: Paletten tauchen aus der Tiefe auf wie Raumschiffe, entfalten Roboterarmen gleich ihre Menüs, gleiten majestätisch in den Orbit...
Noch wird es eher als Kuriosum für Nerds wahrgenommen, aber im Moment liegt beim W3C ein Working-Draft für die 3-dimensionale Transformation von CSS-Elementen vor. Und dieser Draft ist vielversprechend. Öffnet das folgende Beispiel, um zu sehen, was man mit 4 DIVs ohne eine Zeile Javascript machen kann:
Beispiel öffnenBevor Ihr nun loszieht um endlich die ultimative Startrekmatrixminorityreport-Navigation zu bauen, von der Ihr geträumt habt, seitdem Ihr mit 14 das erste Millenium-Falcon Poster an die Wand gepinnt habt: wie immer hat die Sache einen Haken. Da es sich um einen Draft handelt, ist die Browserunterstützung noch verschwindend gering. Genauer gesagt: Safari und zwar nur auf iPad, iPhone, iPod-Touch und unter Leopard. Das könnte sich aber schon bald ändern: Es ist zu erwarten, dass die meisten auf Webkit basierenden Browser in näherer Zeit nachziehen werden. Gerade für Entwickler auf den diversen mobilen Plattformen ergeben sich dann völlig neue Möglichkeiten, denn Webkit ist hier bekanntlich stark vertreten. Designer, die mit der Entwicklung von HTML-Apps für Mobilplattformen beschäftigt sind sollten sich also schonmal in Stellung bringen. Ich werde in dieser kleinen Serie versuchen, einen kurzen Überblick über den derzeitigen Stand von 3D CSS-Transformationen zu geben. Dieser erste Teil beschäftigt sich mit den Basis-Attributen. Im zweiten Teil werde ich dann näher auf Transformationsmatrizen eingehen. Im letzen Teil lernen wir an einem kleinen Beispiel 3D-CSS in Verbindung mit Javascript kennen. Im Vorbeigehen werden wir uns dabei etwas mit höherer Mathematik (Quaternionen irgendwer?) und natürlicher Objektrotation beschäftigen.
Meine DIVs in 3D???
CSS 3D Transformationen sollen dem Designer ermöglichen, CSS-Elemente nicht nur in der Fläche (x, y, top, left, right, bottom), sondern auch in der Tiefe (z) zu verzerren. Das mag erstmal nach Spielerei aussehen, kann aber, geschickte Verwendung vorausgesetzt, durchaus praktischen Mehrwert bringen. CSS-3D-Transformationen können, besonders in Verbindung mit CSS-Transitions, dazu beitragen, ein Interface besser in einzelne Abschnitte zu gliedern und gleichzeitig die Wechsel zwischen diesen Abschnitten nachvollziehbar zu machen.
Außerdem: ich ziehe es vor, viele Werkzeuge im Koffer zu haben. Alle Hilfsmittel, die mir erlauben, ein Nutzererlebnis zu bereichern sind mir Willkommen. Gerade im Bereich mobiler interfaces bin ich dankbar für jedes Instrument das hilft, mit der wertvollen Ressource Bildschirmfläche zu haushalten.
Die Situation
Um die Beispiele ansehen zu können, braucht Ihr einen Browser, der CSS 3D-Transformationen versteht. Derzeit sind das:
- Safari unter MacOSX 10.6
- Webkit Nightly Build unter MacOSX <10.6
- Safari Mobile auf iPad, iPod-Touch & iPhone
Der aktuelle Nightly-Build von Webkit für Windows unterstützt leider noch keine CSS3D-Transformationen. Ich kann nur dazu raten, immer mal wieder zu überprüfen, ob sich der Funktionsumfang geändert hat.
Derzeit sind CSS 3D Transformationen also vor allem für Entwickler interessant, die HTML-Apps für die iPhone/iPad-Plattform entwickeln wollen.
Welche Browser werden den Standard unterstützen?
Es ist am wahrscheinlichsten, dass zuerst weitere Webkit-basierte Browser den Standard übernehmen. Webkit liegt neben Safari auch Googles Chrome zugrunde. Im Desktop-Bereich ist Webkit zwar nicht so dominant, auf Smartphones ist es allerdings die meistverbreitete Rendering-Engine, wenn auch in stark voneinander abweichenden Ausprägungen.
Step by Step Walkthrough:
Designer mit einem Hintergrundwissen aus dem 3D-Animationsbereich sollten keine allzu hohen Erwartungen stellen: es gibt es z.B. weder eine Kamera, noch Shader oder Lichtquellen. Die Navigationsmöglichkeiten sind ebenfalls sehr eingeschränkt, da der tandpunkt nicht rotiert werden kann. Auch Designern, die schon mit 3D-Modellling zu tun hatten, werden einige Konzepte sehr Abstrakt erscheinen (was sind Transformationsmatrizen?) auch die Wechelwirkung zwischen dem 3D-Element und den übrigen Elementen auf der Seite ist nicht unbedingt immer plausibel (wie verhalten sich Floats? Was ist mit Margins?).
Aber bevor wir weitermachen, spielt am besten erst einmal mit dieser Demo herum. Hier könnt Ihr die einzelnen Attribute verändern und die Wirkung dann auch direkt erleben. Das hilft hoffentlich, die abstrakte Materie etwas zu veranschaulichen.
Beispiel öffnenDas Beispiel lehrt uns nebenbei noch etwas über den enttäuschenden Umgang von Safari mit SVG-Hintergrundgrafiken. Da die Hintergrundbilder als SVGs eingebettet wurden, wäre zu erwarten, dass sie immer randscharf dargestellt werden, egal wie stark man sie verzerrt. Leider ist das nicht der Fall, denn der Browser wendet die Verzerrung nur auf ein Bitmapcache an.
Dann wollen wir also mal ein einfaches HTML-Dokument anlegen:
<div id="container"> <div id="child"> </div> </div> Als nächstes soll das div#child gedreht, skaliert und verschoben werden. Vorher müssen wir dem div#parent allerdings mitteilen, dass es auf seine Kinder eine räumliche Darstellung anwenden soll (beachtet das herstellerspezifische Präfix "-webkit-" vor allen CSS-Attributen). Der entsprechende Stylesheet:
div#container{ -webkit-perspective: 250px; -webkit-perspective-origin: 50% 80%; } 
Diese beiden Angaben bereiten lediglich unsere Bühne vor. Keine der Angaben bewirkt eine Veränderung von "container". Wir legen hier nur fest, wie Kindelemente von "container" gerendert werden.
Das Konzept hinter „perspektive„ ist nicht ganz leicht zu verstehen. Stellen wir uns vor, dass zwischen dem Betrachter und der z=0 Ebene eine Pyramide wäre (Siehe Abbildung), dann wäre „Perspective” die Entfernung der Pyramide, von der Basis bis zur Spitze. Man kann Perspective mit der Änderung des Bildwinkels am Kamera-Objektiv vergleichen, eine Verzerrung und Streckung in der Tiefe. Je größer dieser Wert, desto spitzer die Pyramide und desto mehr entspricht die Darstellung der untransformierten Größe, weil die Verzerrung bei der Projektion weniger stark ausfällt. Als Faustregel gilt: Wert zwischen 700 und 1000 werden als "normal" empfunden und sind eine gute Ausgangsbasis.
„perspektive-origin” legt die Koordinaten des Perspektivmittelpunktes fest. Stellen wir uns kurz vor, wir würden eine Kamera installieren um unsere 3D-Szene zu Photografieren: „perspektive” wäre in diesem Falle der Bildwinkel am Kameraobjektiv, mit „Origin” werden die x- und y-Koordinate der Kamera festgelegt. In unserem Beispiel haben wir für „Origin” einen prozentualen Wert verwendet. Es ist aber ebenso gestattet, den Wert in anderen Maßeinheiten (px, cm, in, em etc..) oder absolut (left, top, right, bottom, center) anzugeben.
Wir haben nun die Bühne vorbereitet, kommen wir also zum Kindelement, welches transformiert werden soll:
- Der Ursprung der Transformation soll in mitte liegen.
- Das Element soll 50px auf der X-Achse, 40px auf der Y und 80px auf der Z-Achse verschoben werden.
- Anschließend wollen wir seine Breite verdoppeln und es dann 45 Grad um die Y-Achse drehen:
div#child{ -webkit-transform-origin: 50% 50% 50%; -webkit-transform: perspective(0) translate3d(50px, 40px, 80px) scale3d(1, 2, 0) rotate3d(0, 1, 0, 45deg); -webkit-transform-style: preserve-3d; } transform-origin:
Mit dem "transform-origin" wird der Mittelpunkt von dem die Transformation ausgeht festgelegt. Für die zulässigen Maßeinheiten gelten dieselben Regeln wie für die Angaben zur "perspective". Ein Z-Wert ist in der Spezifikation ausdrücklich vorgesehen, hatte aber bei keinem meiner Experimente eine Auswirkung.
transform: ...
Dieses Attribut fasst alle Transformationen zusammen:
- perspective(val)
- translate3d(x, y, z)
- scale3d(x, y, z)
- rotate3d(x, y, z, winkel)
transform: perspective(val)
Die Kurzversion von „perspective:val”, diesmal nicht erst auf dem Container sondern direkt auf dem Objekt. Die Deklaration wirkt sich also direkt auf den Träger aus. Falls es schon eine "perspective"-Deklaration auf dem Parent-Objekt gab, addieren sich die beiden Werte.
transform: translate3d(x, y, z):
Eine perspektivische Verschiebung auf der entsprechende Achse
transform: scale3d(x, y, z)
Skaliert das Objekte auf der jeweiligen Achse. Ein Wert von 1 bedeutet dass keine Skalierung stattfindet. Da ein Blockelement keine Dicke hat, scheint eine Skalierung auf der Z-Achse sinnlos. Bedenkt aber bitte, dass es z.B ohne weiteres möglich ist z. B. eine Gruppe von DIVs zu erstellen, die einen Würfel bilden. Diese Gruppe könnte anschließend auch in der Tiefe skaliert werden.

transform: rotate3d(x-vektor, y-vektor, z-vektor, winkel)
Eine Rotation um eine Vektorachse: zuerst wird der Vektor, um den die Rotation stattfinden soll festgelegt. Wichtig ist dabei das Verhältnis der Vektorwerte für x, y und z zueinander, nicht ihre Einzelwerte. D. h. rotate3d(5, 6, 10, 45deg) wird denselben Effekt haben wie rotate3d(50, 60, 100, 45 deg). Der letzte Wert ist dann der eigentliche Winkel, der in Grad (deg) und in Radian(rad) angegeben werden kann.
-webkit-transform-style:
Dies ist wieder ein Attribut, das sich erst auf das Kindelement auswirkt. 2 Werte sind möglich: "preserve-3d" und "flat".
- „preserve-3d” behandelt Kindelemente ebenfalls als 3-Dimensionale Objekte in demselben Koordinatensystem wie das Elernelement.
- „flat” verwandelt Kindelemente wieder in 2-Dimensonale Flächen, die wie eine Textur flach auf das Elternelement projiziert werden.
Es gibt noch weitere Transformationen, die ich an dieser Stelle nicht aufgeführt habe, weil ich denke, dass ihre Bedeutung selbsterklärend ist:
- translateX(x)
- translateY(y)
- translateZ(z)
- rotateX(angle)
- rotateY(angle)
- rotateZ(angle)
- backface-visibility: visible | hidden
Bleibt noch die Transformationsmatrix matrix3d(…), die ich das nächstemal etwas ausführlicher behandeln werde.
Tweet me!"
I really love the ne CSS3 Modules, but there will be a long way to go until all the major browser (including IE) support these features ;o(
Nice looking article. Great demo. Thanks!
Brilliant!
Thank you
J
You’ve talked about webkit, but have the other browsers expressed any interest in supporting this? Or is there no information either way?
A the moment only Webkit offers CSS3D transforms, even though I heard rumors that firefox wont to include them in a future release. The technology is still in it’s early stages and I wouldn’t recommend using it outside of IOs.
Thanks for writing this article. It helped when I was building out this coverflow using CSS 3D transforms: http://scottgale.com/blog/coverflow-css-3d-transforms/2011/05/24/
Hi Scott, great to hear that it was useful for you. And great demo too.
My God man! :D All I want to know how to transform a DIV into a trapezoid! I just want a block of text to look like the top is bigger and wider than the bottom. Can someone give me a quick code snippet?
Hi David, right now this is only possible with css3d transfoms. Use something like “-webkit-transform: perspective(700) rotateZ(45deg);”. Anyway this is not a true irregular distortion but a perspective distortion. And it will only show up in supporting browsers.