Animated CSS3 cube using 3D transforms

Last week WebKit included the much antic­i­pated (at least on my part) 3D trans­forms in its lat­est nightly build, announced prac­ti­cally along­side the awe­some Snow Stack demo that pro­vides a 3D inter­face for brows­ing Flickr images (use left, right and space-bar). Today the Surfin Safari blog has updated with some more excit­ing demos, includ­ing “Mor­phin Power Cubes” and “Poster Cir­cle”. It is now pos­si­ble to cre­ate all sorts of crazy three-dimensional and ani­mated user inter­faces; the power comes largely in -webkit-perspective and a num­ber of updated transforms–adapted to incor­po­rate the Z axis.

Since work­ing on the 3D cube using 2D trans­forms back in April I’ve exper­i­mented with per­spec­tive to cre­ate some­thing more pow­er­ful, play­ing around with 3D trans­forms on the iPhone a few times (e.g. this early rotat­ing demo). Now I’ve got some­thing worth sharing.

A 3D cube can be cre­ated solely in CSS, with all six faces. Using JavaScript to detect key presses and update inline styles this cube can be intu­itively navigated.

Result

A 3D cube that rotates using the Up, Down, Left and Right arrow keys.
Sup­ported browsers: WebKit Nightly r46042+

3D cube interface using new WebKit transforms

How To

I’ll start with the markup, because it’s sim­ple. Each of the six cube faces is given a face class and another relat­ing to it’s num­ber. These six faces sit within a cube con­tainer, which sits in another wrap­per, each is necessary.

<div id="experiment">
	<div id="cube">
		<div class="face one">
			One face
		</div>
		<div class="face two">
			Up, down, left, right
		</div>
		<div class="face three">
			Lorem ipsum.
		</div>
		<div class="face four">
			New forms of navigation are fun.
		</div>
		<div class="face five">
			Rotating 3D cube
		</div>
		<div class="face six">
			More content
		</div>
	</div>
</div>

The outer wrap­per serves as a cam­era, on which you apply some per­spec­tive — appro­pri­ate 3D trans­for­ma­tions are then applied to descen­dants. -webkit-perspective defines the depth of the Z-plane and rel­a­tive sizes of ele­ments above and below it, -webkit-perspective-origin spec­i­fies the perspective’s ori­gin. View a per­spec­tive exam­ple (webkit​.org)

    #experiment {
      -webkit-perspective: 800;
      -webkit-perspective-origin: 50% 200px;
    }

The sec­ond con­tainer, the actual cube, has a spec­i­fied height, mar­gin, posi­tion, etc. as usual. The height and width are nec­es­sary to cre­ate some con­fines for the cube face trans­for­ma­tions — alter­na­tively the width defaults to 100% and the cube’s appear­ance would vary with win­dow width. -webkit-transition (doc­u­men­ta­tion) defines the ani­mated prop­erty, dura­tion and timing-function — we’re ani­mat­ing the 3d trans­for­ma­tion (via -webkit-transform) lin­early for two sec­onds. -webkit-transform-style deter­mines whether child ele­ments lie flat against their par­ent (“flat”) or remain in 3D space (“preserve-3d”).

    #cube {
      position: relative;
      margin: 0 auto;
      height: 400px;
      width: 400px;
      -webkit-transition: -webkit-transform 2s linear;
      -webkit-transform-style: preserve-3d;
    }

Using the .face class com­mon styles are applied to the six sides; col­or­ing, size, padding, etc. Impor­tantly they are each posi­tioned absolutely, rel­a­tive to the cube con­tainer. The back­ground rgba prop­erty is included to make the cube look pretty and transparent.

    .face {
      position: absolute;
      height: 360px;
      width: 360px;
      padding: 20px;
      background-color: rgba(50, 50, 50, 0.7);
    }

Each of the faces, one through six, needs to be rotated in 3D space to its cor­rect start­ing posi­tion. Using translateZ the ele­ments are brought 200px (half their width) off the Z-plane. Each of the faces must be at 90 degrees. Rotat­ing solely in the X plane posi­tions the top and bot­tom faces (one, six), before rotat­ing the last four faces in the Y plane, much like origami. The extra rotate on the sixth face rotates the con­tent in 2D space to cor­rect its orientation.

    #cube .one  {
      -webkit-transform: rotateX(90deg) translateZ(200px);
    }

    #cube .two {
      -webkit-transform: translateZ(200px);
    }

    #cube .three {
      -webkit-transform: rotateY(90deg) translateZ(200px);
    }

    #cube .four {
      -webkit-transform: rotateY(180deg) translateZ(200px);
    }

    #cube .five {
      -webkit-transform: rotateY(-90deg) translateZ(200px);
    }

    #cube .six {
      -webkit-transform: rotateX(-90deg) translateZ(200px) rotate(180deg);
    }

Our cube is now com­plete — but it doesn’t move! With a key­down event lis­tener we can incre­ment X and Y angles based on dif­fer­ent key presses, before apply­ing them as inline styles on the cube con­tainer. In com­bi­na­tion with the tran­si­tion effect on #cube, all six faces rotate in sync from their orig­i­nal posi­tion to the newly defined angle, cre­at­ing a seam­less 3D cube interface.

  	var xAngle = 0, yAngle = 0;
	document.addEventListener('keydown', function(e)
	{
		switch(e.keyCode)
		{

			case 37: // left
				yAngle -= 90;
				break;

			case 38: // up
				xAngle += 90;
				break;

			case 39: // right
				yAngle += 90;
				break;

			case 40: // down
				xAngle -= 90;
				break;
		};

		$('cube').style.webkitTransform = "rotateX("+xAngle+"deg) rotateY("+yAngle+"deg)";
	}, false);

15 Comments

  1. Aimee Graham

    That is one of the most amaz­ing things I have seen in a while. Could this also be poten­tially moved by click­ing or hov­er­ing in a cer­tain area of the cube?

  2. Oyun Oyna

    great thanks for post.

  3. ardianzzz

    Wow! amaz­ing!

  4. dioxyd

    I am not able to see the pre­view in any of my cur­rent browsers?

    Here they are:

    1– Firefox/3.6 (.NET CLR 3.5.30729)

    2– Inter­net Explorer 8.0.6001.18882

    I just see lit­tle Sonic animation.

  5. b

    :( soo sad. I can’t see the 3d effect…they are all stacked up. and I have the lat­est ver­sion of Fir­fox (3.6) on mac … am I miss­ing something?

  6. Rogers

    but not dis­play­ing i IE

  7. Chris

    All above who are using Fire­fox or IE, this doesn’t work. Those aren’t webkit-based browsers. Chrome and Safari are…

  8. omegared

    like — I am espe­cially excited about the pos­si­bil­i­ties of using this with the iphone for navigation

  9. eyesoo

    太强大啦。我顶!

  10. Vilic

    强大!
    Thx a lot!

  11. Mike

    sadly, this is not work­ing in the lat­est ver­sion of chromium

  12. damu

    wow! excit­ing stuff :)

  13. Tracy Hare

    Great writeup! Got my panorama cube with no prob­lem. Any idea how to get the point of view inside the box?

  14. Marc Drewello

    Its very nice but i have two ques­tions! add my @twitter i fol­low u “Plextron”

    Greetz Marc

  15. christopher scott

    This is a really good exam­ple of the var­i­ous webkit props… thanks for writ­ing this up.