Page 1 of 1

Advanced CSS3: 3D Cube Tutorial Rate Topic: ****- 2 Votes

#1 Vip3rousmango  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 56
  • View blog
  • Posts: 98
  • Joined: 10-February 10

Posted 25 March 2011 - 10:38 PM

Tutorial: Advanced CSS3 :: 3D Cube with Safari -Webkit

Intro

Hello D.i.C,
This is my first tutorial so please comment and let me know if you find this helpful. I did some searching and found nothing like this yet so I thought I'd contribute, maybe teach a thing or two.

**** Notes: This tutorial assumes you already have an intermediate understanding of CSS (using everything up to browser specific gradients) and a basic understanding of HTML. We are going to achieve a rotating 3D cube using only CSS3 and some images without a long amount of coding. ****

From a design standpoint this really isn't that practical right now, but I thought we could have some fun with CSS 3 and what will be soon available in browsers so D.i.C. members can get the drop on the competition and display some awesome design skills. This also highlights the power of CSS 3 and what the future holds for design!!

Features & Highlights:

The 3D cube will rotate around 360 degrees in place with each side dynamic and clickable only when in view. You could pick any pictures you want as long as they are square in sizing (both height and width are equal). I have yet to test this with .swf and have no idea if that would work.

About CSS Animations:

CSS Animations is one of the enhancements to CSS proposed by the WebKit project that has been labeled "CSS Effects" (eg. gradients, masks, transitions). The goal is to have properties that allow Web developers to create graphically rich content. In many cases animations are presentational, and thus should belong within the styling system.
This allows developers to write declarative rules for animations, replacing lots of hard-to-maintain animation code in Javascript.

If you're interested on learning more they are documenting these enhancements on webkit.org and are proposing the specifications to standards bodies. Note that since they are currently features specific to WebKit they are implemented with a -webkit- prefix, although the specifications do not use the prefix.

Requirements:

The good news is that the WebKit on iPhone 2.0 already supports CSS Animations (as well as CSS Transforms and CSS Transitions). The iPhone implementation has been optimized for the platform so you get fantastic performance. Combining animations, transitions and transforms allows for some really impressive content!

You will need Nightly Webkit for your computer in order to test and view your completed cube properly, OR you can use the Safari browser on your iPhone 2.0+!
These CSS features arn't currently supported by modern browsers, only a select one. Because of that, trying to implement this won't be easy until browsers update their support, which will hopefully be soon!
--------------------------------------------------------------------------------------------------------------------------

Lets Get Started: HTML Markup


------>>> You can check out my 3D CSS Cube here. This is what we'll be making today. ONLY WORKS in SAFARI FOR IPHONE 3GS/4 or INSTALL: Nightly Webkit <<<------

We are going to start with a new HTML document inside your favourite editor and use some basic HTML5 markup for the base:
<!DOCTYPE HTML>
<!-- 
Created by: Vip3rousmango
Author URL: http://www.virtuallycreative.ca
Date: March 25th 2011
Project: Advanced CSS Tut
Description: Floating 3D cube using CSS only -webkit & Safari Nightly Browser!
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS Floating Cube Tut</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
</head>

<body>

</body>
</html>


Inside <body> we'll add our 6 sides to the cube:
	<div id="container">
		<div id="shape">
		<div class="one"><a href="http://dev.virtuallycreative.ca/folio1.html"><img src="images/service1.jpg" alt=""></a></div>
		<div class="two"><a href="http://dev.virtuallycreative.ca/folio2.html"><img src="images/service2.jpg" alt=""></a></div>
		<div class="three"><a href="http://dev.virtuallycreative.ca/folio3.html"><img src="images/service3.jpg" alt=""></a></div>
		<div class="four"><a href="http://dev.virtuallycreative.ca/folio4.html"><img src="images/service4.jpg" alt=""></a></div>
		<div class="five"><a href="http://dev.virtuallycreative.ca/folio5.html"><img src="images/service5.jpg" alt=""></a></div>
		<div class="six"><a href="http://dev.virtuallycreative.ca/folio6.html"><img src="images/service6.jpg" alt=""></a></div>
		</div><!-- /shape -->
	</div><!-- /container -->



So whats going on here? Inside the <body> tag we added a <div> with an id of container which holds the <div> with an id of shape. The <div id=shape> holds the six sides of our cube, and will be assembled like a puzzle, side by side. I desided to use individual <div> tags for each side of the cube with just an anchor and an image tag in each with individual classes assigned rather than using lists or spans because I find this method of using individual <div>'s easyer for styling and managing the behaviour of CSS's parent/child relationship and keeping things simple for this tutorial example.

This completes the HTML of the cube! The final markup now looks like this:
<!DOCTYPE HTML>
<!-- 
Date: March 25th 2011
Project: Advanced CSS Tut
Description: Floating 3D cube using CSS only -webkit & Safari Nightly Browser!
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS Floating Cube</title>
<link rel="stylesheet" href="css/style.css" type="text/css" />
</head>

<body>
	<div id="container">
		<div id="shape">
		<div class="one"><a href="http://dev.virtuallycreative.ca/folio1.html"><img src="images/service1.jpg" alt=""></a></div>
		<div class="two"><a href="http://dev.virtuallycreative.ca/folio2.html"><img src="images/service2.jpg" alt=""></a></div>
		<div class="three"><a href="http://dev.virtuallycreative.ca/folio3.html"><img src="images/service3.jpg" alt=""></a></div>
		<div class="four"><a href="http://dev.virtuallycreative.ca/folio4.html"><img src="images/service4.jpg" alt=""></a></div>
		<div class="five"><a href="http://dev.virtuallycreative.ca/folio5.html"><img src="images/service5.jpg" alt=""></a></div>
		<div class="six"><a href="http://dev.virtuallycreative.ca/folio6.html"><img src="images/service6.jpg" alt=""></a></div>
		</div><!-- /shape -->
	</div><!-- /container -->

</body>
</html>


Lets Get Started: CSS Markup

So the HTML wasn't to hard was it? Not to much going on, the magic is in the CSS. If you preview what we get in any browser (or your new Nightly Webkit Browser) you should end up with something like a column of images all to one side. This is good, so now it is time to style.

Make a new file and call it style.css and save it inside a folder called "css" in the same directory as the cube.html file. This will allow your <link> path we used in the HTML to work and find the correct stylesheet!

Once that is complete we're going to start styling the elements one at a time, first let's give the background a nice CSS3 webkit gradient & don't forget your comments so you know what project this is:
/*
Created by: Vip3rousmango
Author URL: http://www.virtuallycreative.ca
Date: March 25th 2011
Project: Advanced CSS Tut
Description: Floating 3D cube using CSS only -webkit & Safari Nightly Browser!
*/
body {
	background: -webkit-gradient(radial, 800 64, 950, 500 400, 40, from(#1F1F1F), to(#FFFFFF)); /*background Gradient */
}


Next, we'll align the container div to make it center:
html, body {
	width: 100%;
	height: 100%;
    overflow: hidden;
}
#container {
 width: 100%;
}



The next step is to style our Shape <div> so lets add some style to that. This step is important as it defines the dimensions of the cube. We could use a background colour but since the images of each side are going to take up the whole space, we don't really need one in this case:
/* Cube Layout */
#shape {
	position: relative;
	top: 160px;
	margin: 0 auto;
	height: 200px; /* Will be the height of Cube */
	width: 200px; /*Will be the width of Cube */
}


Once that's done we need to style the individual "sides" of the cube. So we need to isolate and style each image tag:
#shape > div {
	position: absolute;
	height: 200px; /* Each "Side" of Cube, must match original cube Height above */
	width: 200px; /* Each "Side" of Cube, must match original cube Width above */
	border: 1px solid #e3e3e3;
	-webkit-border-radius: 10px;
	
	}

	#shape > div img {
	width: 100%; /* Forces image to all space of container */
	height: 100%; /* Forces image to all space of container */
	}



And their we go, we can now start the coding for making the animation and turning the side <div>'s to 3D "space". If you notice we havn't made our side's class yet! We will do this while we add in the CSS markup to create the rotation animation.

Up until now, the only intermediate concept shown was the -webkit-gradient() property. If you're having trouble with anything up until this point, you might want to go back and double check things to make sure you're familiar with their usages and what they do. It honestly comes down to memorization and repetiton.

At the moment, if you preview what we've done so far in Nightly (which you should be doing all along..) it doesn't resemble much like a cube. And it won't for a while FYI, and this is ok.

Advanced CSS Styling

Moving on, we are going to add our first advanced Webkit property:
-webkit-transition: -webkit-transform 2s;

This is added to #shape > div property. For us, we put it on line 8 below. Add it to your style.css #shape > div now:
#shape > div {
	position: absolute;
	height: 200px; /* Each "Side" of Cube */
	width: 200px; /* Each "Side" of Cube */
	border: 1px solid #e3e3e3;
	-webkit-border-radius: 10px;
	
	-webkit-transition: -webkit-transform 2s;
	}


So what's going on here? Normally when the value of a CSS property changes, the rendered result is instantly updated, with the element in question changing immediately from the old property value to the new property value. Transitions describe how to instead execute an animation from the old state to the new state over time. So rather than change instantly when calling a transition we're telling the CSS that the transistion should be a 2 second long transform instead.

Now we're going to back to the #shape property. We create our custom animation here since this is the <div> we want to animate on the page. So here comes property #2 to add:
-webkit-animation: spin 30s infinite linear;

Whats going on here? As a counterpart to transitions, animations provide a way to declare repeating animated effects, with keyframes, completely in CSS! No more flash for this guy!

Usage is -webkit-animation: name duration iteration-count direction;

You can make the name anything you want, for our example I choose spin, since that's what the cube will be doing. For duration I set 30 seconds, this how long the total animation will be start to finish. Interation-count is infinite because I don't want the spinning to end, ever. The direction is how the animation moves and we're going with linear since it should spin across 1 plane out of 3.

But wait! You saved and checked your work and nothing has happend. Thats right. -webkit-animation requires another property to run.

We follow up with property #3:
@-webkit-keyframes spin {
	from { -webkit-transform: rotateY(0) rotateX(0); } 
	to { -webkit-transform: rotateY(-360deg) rotateX(360deg); }
		}


What's going on here? So a keyframe defines the style that will be applied for that moment within the animation. The animation engine will smoothly interpret style between the keyframes. Here we made two keyframes, from and to. They tell the cube to start at 0 degrees on both the X and Y-axis and then move to a full 360 degree rotation around both plains. We add it to our style.css between #shape and #shape > div and all together should look like:
#shape {
	position: relative;
	top: 160px;
	margin: 0 auto;
	height: 200px; /* Height of Cube */
	width: 200px; /*Width of Cube */
	
	/*Govern's Custom Animation's Paramaters */
	-webkit-animation: spin 30s infinite linear; /* Creates Custom "Spin" Animation for 30sec never-ending */
}
/* Create Spin Animation */
	@-webkit-keyframes spin {
		from { -webkit-transform: rotateY(0) rotateX(0); } /* keyframe specifics */
		to { -webkit-transform: rotateY(-360deg) rotateX(360deg); }  /*RotateY = full spin, RotateX = full spin */
		}
		
	#shape > div {
	position: absolute;
	height: 200px; /* Each "Side" of Cube */
	width: 200px; /* Each "Side" of Cube */
	border: 1px solid #e3e3e3;
	-webkit-border-radius: 10px;
	
	-webkit-transition: -webkit-transform 2s;
	}


Now here is the fun part: Save your work, refresh your page and now your animation should start to spin! Not a cube yet, but big things are happening! You just made your first animation using only CSS3! Congrats!

Don't stop now, we're so close to bringing it all together.

So since you saved your work and you're being careful (right?) you can have some fun and play around with to's rotateY() and rotateX() paramaters, try some things out and see what happends during the rotation animation. Trial and error here are the best ways for learning some cool combinations.

Final Stage: CSS Cube Classes

Thats right, it's now time to start styling each side of the cube. This is probably the most confusing part of the whole tutorial so I'll try to do my best to explain as clearly as possible. As I said earlier we decided to use a class to handle each side so lets make them now and introduce our next CSS property:
-webkit-transform: rotateX(90deg) translateZ(100px);


We create our first new class accordingly on the next available line below #shape > div img:
.one {
    -webkit-transform: rotateX(90deg) translateZ(100px);
}


Whats going on here? -webkit-transform supports a list of functions, where each single function represents a transform operation to apply. You can chain together operations to apply multiple transforms at once to an object (e.g., if you want to both scale and rotate a box at the same time). RotateX() determines the angle in which the container is displayed at. Since a cube has all 90 degree angles, we set it to 90degrees. TranslateZ() determins positions along the Z-axis, which runs front to back in 3-D space. Positive values position the element closer to the viewer, negative values further away.

Pretty cool huh! So using a combination of these two operations we can achieve our cube layout. Save your work and check it out now. As you can see still not a cube yet, we need to do more sides and then you'll see it starting to take effect.

But, before we continue making our side classes, their are two things that must be looked at when talking about translateZ(). Like translateZ() we are going to need something to control perspective of the whole 3D cube, not just one side's perspective. We can set this by adding a new paramater:
-webkit-perspective: 800;

Since we want to affect the perspective of the whole cube, not just one side we're going to add this to our #container tag, so update it now so it looks like this:
#container {
 width: 100%;
 /*Set's P.O.V */
 -webkit-perspective: 800;
}



What's going on here? We use -webkit-perspective: to give an illusion of depth; it determines how things change size based on their z-offset. Thus, large values give a little foreshortening effect, and small values lots of foreshortening. Values between 500px and 1000px give a reasonable-looking result for most content. I picked 800, but try out some different numbers and refresh your work to see how it works. Once you're done set it too 800 and continue.

So this is all fine and dandy but now we have run into a problem. We've brought the parent element into the 3D plane and made it rotate, but all the children are still flat. We need to find a way to specify that any children, our images, can also "live" in a 3D environment. To do this we're going to set a new property:
-webkit-transform-style: preserve-3d;

We set this property inside the #shape tag since it is the parent <div> like so:
#shape {
	position: relative;
	top: 160px;
	margin: 0 auto;
	height: 200px; /* Height of Cube */
	width: 200px; /*Width of Cube */
	
	/*Govern's Custom Animation's Paramaters */
	-webkit-animation: spin 30s infinite linear;

	/* Allows child elements (images) to "live in 3D" */ 
	-webkit-transform-style: preserve-3d;
}



So what's going on here? -webkit-transform-style defines how nested, transformed elements are rendered in 3D space.
If -webkit-transform-style is flat, all children of this element are rendered flattened into the 2D plane of the element and won't be visible in 3D space. If -webkit-transform-style is preserve-3d, this flattening does not occur, so children maintain their position in 3D space and can been seen.

So now we can continue on styling the rest of our side classes! If you take a look at your work now, you can start to see the workings of our cube! Told you this would be awesome. But here comes the tricky part, we need to push the rest of our images out from the center of the cube, along the Z-plane so they meet at the edge of our container and join together to visually make our cube. So lets do this now, under .one we begin the next class:
.two {
    -webkit-transform: translateZ(100px);
}


So whats the deal? Well, since elements start at the center of our cube on the z=0 plane, we only need to push .two half of the width of our element to reach the conatiner's edge. Since we set the container's width/height to 200px eariler, we only need to push it 100px to get to the edge of our cube. Try it out: put something larger or smaller than 100px inside and see where image .two goes!

Starting to catch on now after seeing the changes in action?

Let's keep up the pace and continue with .three, it should come after .two:
.three {
    -webkit-transform: rotateY(90deg) translateZ(100px);
}


Now the cube is really coming together, save your work and now it's time for the other sides. This time though, we're going to copy the code for .one and use it for .six since .one and .six should be opposite each other in the cube we can reuse the code, and just reverse the Axis position:
.six {
    -webkit-transform: rotateX(-90deg) translateZ(100px);
}


What's going on here? Like class .one we set the rotateX() and translateZ() paramaters, but this time we made rotateZ(-90deg). This is important since this side is opposite it needs to go the other way! If you don't understand which side is opposite to the other, grab some plain dice from any board game and look which numbers are opposite to which side. That helped me out a lot in knowing which ones to set a positive degree value and which ones negative. The rest is practise and patience.

So lets finish off our last two classes, .four and .five:
.four {
    -webkit-transform: rotateY(180deg) translateZ(100px);
}

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



And that's it! That's all the CSS required to make your cube work! Here is the final CSS file in it's entirity:
/*
Date: March 25th 2011
Project: Advanced CSS Tut
Description: Floating 3D cube using CSS only -webkit & Safari Nightly Browser!
*/
html, body {
	width: 100%;
	height: 100%;
	overflow: hidden;
}

body {
	background: -webkit-gradient(radial, 800 64, 950, 500 400, 40, from(#1F1F1F), to(#FFFFFF)); /*background Gradient */
}

#container {
 width: 100%;
 /*Set's translateZ P.O.V */
 -webkit-perspective: 800;
}
/* Cube Layout */
#shape {
	position: relative;
	top: 160px;
	margin: 0 auto;
	height: 200px; /* Height of Cube */
	width: 200px; /*Width of Cube */
	
	/*Govern's Custom Animation's Paramaters */
	-webkit-animation: spin 30s infinite linear; /*Use: animationNAME | total animation lenth | amount | default swing */
	/* Allows child elements (images) to "live in 3D" */ 
	-webkit-transform-style: preserve-3d;
}
/* Create Spin Animation */
	@-webkit-keyframes spin {
		from { -webkit-transform: rotateY(0) rotateX(0); } /* keyframe specifics */
		to { -webkit-transform: rotateY(-360deg) rotateX(360deg); }  /*RotateY = full spin, RotateX = full spin */
		}
		
	#shape > div {
	position: absolute;
	height: 200px; /* Each "Side" of Cube */
	width: 200px; /* Each "Side" of Cube */
	border: 1px solid #e3e3e3;
	-webkit-border-radius: 10px;
	
	-webkit-transition: -webkit-transform 2s;
	}

	#shape > div img {
	width: 100%; /* Force all space of box */
	height: 100%; /* Force all space of box */
	}
	
	
	
	/* Cube Sides */
	
	.one {
		-webkit-transform: rotateX(90deg) translateZ(100px);
	} /*translateZ must be set in pixels = visual POV perspective */
	
	.two {
		-webkit-transform: translateZ(100px); /*Only push half width of parent container (200px) */
	}
	
	.three {
	-webkit-transform: rotateY(90deg) translateZ(100px);
	}
	
	.four {
	-webkit-transform: rotateY(180deg) translateZ(100px);
	}
	.five {
	-webkit-transform: rotateY(-90deg) translateZ(100px);
	}
	.six {
	-webkit-transform: rotateX(-90deg) translateZ(100px);
	}



Hope you enjoyed this tutorial! I have included a copy of the HTML and CSS source files for reference:
Attached File  index.html (1.22K)
Number of downloads: 534
Attached File  style.css (2.04K)
Number of downloads: 486

Any feedback would be appreciated! Please let me know if you've found any errors and I'll try to correct them ASAP! Thanks so much! Happy coding.

Attached image(s)

  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image


Is This A Good Question/Topic? 1
  • +

Page 1 of 1