After correctly setting perspective there are a few more factors to consider before starting creative work in CSS 3D. Paradoxically, appreciation of the 3D portion of the CSS Transforms spec can also enhance the performance of 2D transitions and animations, as you’ll see in the next article. First, some under-appreciated aspects of CSS 3D:

CSS 3D is Naturally Responsive

A surprising aspect of 3D transforms is that they naturally respond to changes in the size of the viewport. Take the simple example of a div containing an image:

<div class="3d-container">
	<img src="shanghai.jpg" alt="Photograph of Shanghai at night">
</div>

Let’s give the <div> a reasonable perspective value, and rotate the image around Y by 33 degrees. (I’ve dropped vendor prefixes in the CSS declarations for the sake of clarity):

div.3d-container {
	perspective: 1000px;
}
div.3d-container img {
	width: 33%;
	transform: rotateY(33deg);
}
Photograph of Shanghai at night

The image will automatically be one-third the width of its container, which, in turn, will be 100% the width of its parent element. By default, the perspective point will be exactly at the center of the <div>. Assuming there are no fixed widths anywhere, that means that resizing the viewport will not only decrease the width of the <div> and dimensions of the image, but also move the vanishing point. If you’re on a desktop browser, you can see the phenomenon by resizing your window: with the browser wide, the perspective on the image looks correct, but as you narrow the window, the perspective gets tighter, and the image flattens out, with the 3d effect becoming less apparent.

Whether this is a good or bad thing is largely a matter of (ahem) perspective.

Use Just One 3D Container To Ensure That Multiple Elements Share The Same Perspective

As our markup becomes more complex it’s natural to nest elements. This creates a problem when each of those containing elements is provided with a separate perspective value, even if the values are the same. For example, let’s look at the effect of placing two images side-by-side in the same <div>, using the same CSS as above:

Photograph of Shanghai at night Photograph of Sydney Harbour

You can see that both images angle towards the same vanishing point. Now let’s place the images in separate div elements, with both containers using the same class:

<div class="3d-container">
	<img src="shanghai-at-night.jpg" alt="Photograph of Shanghai at night">
</div>
<div class="3d-container">
	<img src="sydney-harbour.jpg" alt="Photograph of Sydney Harbour">
</div>
Photograph of Shanghai at night
Photograph of Sydney Harbour

As you can see, each image now tends toward the vanishing point of its container. Bottom line: unless you want to create disorienting, Inception-like effects, keep elements you’re trying to affect with 3D in the same container, or use the technique below.

Force Child Elements To Inherit 3D

What if you absolutely had to nest elements that will have 3D transforms applied? Let’s keep the basic structure of our code, strip off the classes, and add the obvious: another container around both elements.

<div class="3d-container">
	<div>
		<img src="shanghai-at-night.jpg" alt="Photograph of Shanghai at night">
	</div>
	<div>
		<img src="sydney-harbour.jpg" alt="Photograph of Sydney Harbour">
	</div>
</div>

While this will look fine in current versions of Chrome and Safari, there’s a problem in Firefox: child elements don’t inherit 3D transforms the way they should in Mozilla’s browser. (Remember when I said that CSS 3D wasn’t without its bugs, even in browsers that had dropped vendor requirements for the properties? Yeah, that).

To get propagate 3D through to child elements, place transform-style:preserve-3d on their parents:

div.container {
	perspective: 1000px;
	border: 1px solid red;
}
div.container div {
	transform-style:preserve-3d;
}
div.container div img {
	max-width: 50%;
	transform: rotateY(33deg);
}

This will allow the images to inherit the 3D perspective and transform correctly. It also means that 3D transforms of the parent elements will affect their children, making complex multi-layered 3D transforms possible.

Next in this series, we’ll look at one more common error in setting up 3D transforms, and how to use the syntax to improve the look and feel of your 2D transitions and animations.

Images by Trey Ratcliff, licensed under Creative Commons.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.