DJ Quilter

Front-End Developer

Super Simple 3D Transforms

Creating 3D effects using just plain-old CSS is super-simple, but for me, it did take some time to get my head around what properties you should and shouldn’t be using for the effect I wanted. I’ve used them on my social media buttons. Hopefully this post will help you create your own.

The HTML and CSS is relatively simple, as you can see in the code examples below:

<div class="social-media">
  <ul>
    <li>
      <a href="https://plus.google.com/108919329098908236814/posts" title="Google Plus">
        <div><img src="images/3d-social-media/google-plus.png" alt="Google Plus"></div>
        <div class="activeface"><img src="images/3d-social-media/google-plus.png" alt="Google Plus"></div>
      </a>
    </li>
    <li>
      <a href="https://twitter.com/Quilts85" title="Twitter">
        <div><img src="images/3d-social-media/twitter.png" alt="Twitter"></div>
        <div class="activeface"><img src="images/3d-social-media/twitter.png" alt="Twitter"></div>
      </a>
    </li>
    <li>
      <a href="http://www.linkedin.com/pub/david-quilter/23/62a/957" title="LinkedIn">
        <div><img src="images/3d-social-media/linkedin.png" alt="LinkedIn"></div>
        <div class="activeface"><img src="images/3d-social-media/linkedin.png" alt="LinkedIn"></div>
      </a>
    </li>
  </ul>
</div>

In the HTML, we have a container element, with an unordered list. Each list item includes a link to the relevant profile and two ‘faces’, one for the normal state and the other for the hover state.

.social-media li {
  float:left;
  width:36px;
  height:36px;
  margin:0 6% 0 0;
  list-style-type:none;
  perspective:1000px;
  transform:translateZ(-18px)
}
.social-media li div{
  position:absolute;
  width:34px;
  height:34px;
  border:1px solid #222;
  background-color:#444;
  backface-visibility:hidden;
  transition:transform 1s;
  transform:rotateX(0deg) translateZ(18px)
}
.social-media li:hover div{
  transform:rotateX(90deg) translateZ(18px)
}
.social-media li div.activeface{
  background-color:#222;
  transform:rotateX(-90deg) translateZ(18px)
}
.social-media li:hover div.activeface{
  transform:rotateX(0deg) translateZ(18px)
}
.social-media li a{
  display:block;
  height:100%
}
.social-media li img{
  width:100%;
  height:auto
}
.no-csstransforms3d .social-media div.activeface{
  display:none
}

There are a couple of things to take note of in the CSS I’ve provided here:

  • I have just included the un-prefixed CSS rules for ease of reading (more on that later).
  • I’ve also provided a fallback with the last rule, that relies on Modernizr.

The CSS3 Bits

There are actually very few CSS3 rules used in this example, but for those that I have used, here’s a little description:

Perspective

Perspective defines the space within which the 3D effect occurs. In this example, I’ve used perspective on a container element and then created a 3D object out of it’s children using transforms. In this example, the value that I chose didn’t seem to make a huge difference to the 3D effect unless it was very low (ie single digits). In other examples, I’ve seen, the 3D effect is much more pronounced when the figure is at 200px – 400px. I’ve picked 1000px here, but when you make your own, I would experiment to see what effects you can create.

There is more in-depth information on CSS Perspective out there, but the best that I’ve found is from David DeSandro.

Transform

CSS Transforms are used in two places to position the cube and it’s sides. For the cube’s sides, I found that the best thing to do was to rotate an element on it’s X-axis (if necessary), and then change the Z-axis of each face to position them within the 3D space. So for the ‘hover-face’ (which has the class ‘activeface’), I have rotated it so that it is perpendicular to the ‘normal-face’ and then changed its Z-axis so that it sits at the bottom of our container element. The normal-face has had it’s Z-axis brought forward, so that the two divs create a right-angle.

It’s important that these translations are done in the correct order in your CSS to get the effect that you want. As I was doing this, I found that moving elements on the Z-axis first meant that they ended up in a position which I was not expecting!

The other transform was on the container itself. Because I’d brought the cube forward (via Z-axis on the two faces), I pushed the container back, so that the container’s centre sits at the normal Z-axis position (ie 0 pixels).

Backface Visibility

This one’s fairly simple; as you rotate objects you might end up seeing the rear-side of an element. If you don’t want this to be the case, you simply set it to hidden!

Translation

For the animation, a simple bit of transition is all you need. Use transition on the transform property, and as long as you have your hover states set up correctly, it will all do the business for you!

Compatibility

Generally speaking, your 3D Tranforms will work in all modern browsers. IE9 and earlier will need a fallback. As mentioned earlier, Modernizr can do the hard work for you. All you need to do is make sure you have a good fallback in place!

You’ll notice that the webkit prefix is required for all webkit browsers. As it stands, I think that’s a pretty good set of support!

The Can I Use website can give you up-to-date information on browser support should you need it.

There’s More You Know…

So the example that I’ve created is SUPER-simple, but there is more that you can do with CSS in 3D. Here are some of the sources that I found particularly useful in my research. They should set you on the path to creating your own effects:

  • David DeSandro – Mentioned already, this site is comprehensive!
  • Greensocks – Has some really good examples for getting your head round various concepts.
  • CSS Tricks – As always, full of useful info. I found the property definitions particularly useful (see the bottom of the article for more links).
  • MDN on 3D Transforms