After Effects to CSS 3D workflow – Part 1 – Introduction

Welcome to the first part of the article about the After Effect / CSS 3D Transform transitions workflow : After Effects to CSS 3D workflow – Part 1 – Introduction.
Click here to see the main page of the article :

Part 1: Introduction and CSS


You need some (at least basic) knowledge to follow and apply comfortably explanations :

  • CSS 3 / Javascript
  • Adobe After Effects: UI, expressions and scripting
  • Tweening principle
  • Real-time 3D principle

I try to give details on tricky parts but don’t come back on basics. It already exists a lot a ressources about these topics on the internet. Take a look at the about page to get links for learning general stuffs like these. Despite that, if you need extra clarification or feel it should have few on some points of the article, drop a line in the comments!


I’ve made the first version of this workflow when I thought about the adaptation of my Flash personal website Turbodrive in HTML5. The main ideas were :

  • have something close to the Flash version for the 3D transitions
  • take the occasion of the HTML5 to make the website mobile-compatible and take advantage of the touch screens to improve the user experience.

Scene used as example for the AE to CSS workflow

Compared to Turbodrive, I introduce here a simplified scene for the purpose of the example. In following the explanations you’ll be able to recreate this scene, and so, learn the workflow principles to make it your own.

Selected solutions

After research and tests, the workflow is based on a set of tools.

CSS 3D Transforms

Compatible with modern browsers, including mobile. Only IE doesn’t support (IE 11 in september 2014) some required features in here. Android browser older than KitKat could have some difficulties too.


I’ve found this very useful library in Javascript, developed by boblemarin. It provides an easy way to generate and manipulate DIVs with CSS 3D Transformations.
Especially, there is a great gallery example, which is typically the kind of thing I was looking for my needs of camera transitions. This lib has contributed to chose the CSS 3D Transforms solution.
Here is the github page of the project :

Sure Target principle

Sure target is an After Effects plug-in made by VideoCopilot. This one is pretty interesting in the way you focus on the position of the targeted 3D elements and it interpolates (tweens) camera’s transformations between these targets.
It works with a progress factor defining the camera evolution on a path made by the 3D targets. This progression is only one linear dimension. So in theory it’s compatible with controls such as scroll or touch move (here I’m gonna use a range-input).

You don’t need this plug-in to follow the workflow. I’ve kept the principle of Sure Target only, and you’re gonna code a kind of home-made Sure Target which fit better to our 3D Scene (and the way it’s built).

Adobe After Effects

The software is kind of close to CSS in the way it manages the 3D elements. There is no built-in modeling tool and it’s based on solids (planes) and bitmaps, or other 2d footages… You can especially take the advantages of this powerful UI and features such as layers, nested compositions, timeline…
The AE scripting system in JS allows to effectively add features to the software. You’ll use it to export data in JSON and then manipulate it in the HTML5 project.
In short, it’s easy to go from AE to CSS 3D Transforms.

Instead of AE, I’ve thought about developing a tool made in JS, but it would take longer to build it as much functional as AE.


Workflow setup steps

Pros / Cons


  • Wider browsers support than WebGL
  • 3D pages made in CSS are still crawlable by search engine robots.
  • Accuracy in locating elements in space : you focus on transitions, camera movements and layout.
  • Touch move compatible (and accelerometer too, even if not directly related)
  • JSON export from AE means you can manipulated exported data from anything you want, not only CSS or Javascript.
  • AE is dedicated to motion design. It’s full of the features you want.
  • CSS is pretty lightweight for small 3D scene


  • You need AE and knowledge about how it works.
  • The AE setup could appear a bit complicated.
  • The camera follows a path, so it’s guided and there is no totally free movements.
  • CSS 3D Transforms are limited (the skybox for example, isn’t very well supported on some browsers)


To make explanations simple, let’s use some conventions.

  • AE means one or several element(s) (null object, composition, ) in After Effects.
  • CSS means one or several HTML elements transformed with CSS 3D Transforms (often a Sprite3D, or a DIV) and driven by JavaScript.
  • FCameraCSS, it’s a generic term I use for the CSS setup enabling to transform the 3D point of view.
  • FCameraAE means the 2 layers in AE which behave in the same way as the FCameraCSS. It’s composed by a null object and a composition to recreate the property rotateFirst enabled of the Sprite3D.
  • targetsContainer is pretty similar to FCamera, but in this case it’s mentioned as a container only (a composition in AE or a Sprite3D in JS).
  • targetsContainerAE means the composition itself while FCameraAE includes the null object.
  • targets3D are the 3D elements targeted by the FCamera. Commonly they are also the container of the website pages, spread out in 3D space.
  • target3DCSS means a Sprite3D with rotateFirst disabled.
  • target3DAE means a combo of 3 layers (2 null objects + 1 composition) to recreate the behavior of a Sprite3D with rotateFirst disabled.
  • target3DController is a null object, located in interactiveContainerAE, linked to a target3D and used to control this.

Setting up the 3D Scene with Sprite3D.js

Let’s organize directly the 3D Scene and study the Sprite3D.js specificities. You should understand the 3D CSS Transforms logic to bring it toward AE, and then, extract data from AE to CSS.

The scene is directly inspired by the gallery example. It’s precisely the way this scene has been made which provides a camera behavior in CSS, though there is no camera in CSS.
Actually, a important feature of Sprite3D.js contributes to have this fake camera behavior (= FCameraCSS) : the setRotateFirst() method. This essential method is only available in an old Sprite3D.js version. You can download this here : This is the one I use in this article.

setRotateFirst() explained

This well-named method provides a way to define in which order you want to apply 3D transforms : translations or rotations first (since the 3D transformations perform differently depending on this order).

setRotateFirst(false) or default
└─> translate3d(x,y,z) rotateZ(rotZ) rotateY(rotY) rotateX(rotX);

└─> rotateX(rotX) rotateY(rotY) rotateZ(rotZ) translate3d(x,y,z);

The key of the gallery example above is basically :

  1. A main Sprite3D container, with rotation transformations applied first. This container is put on the stage (kind of “global” or “super” container).
  2. Several Sprite3D, nested in the main container, all of them with different positions and rotations and all of them with the rotateFirst value disabled (default value).
  3. To get one of the child Sprite3D flat centered on screen, we take its coordinates and give their opposite values to the main Sprite3D container. In this way, and in the local space of the targeted child, the main Sprite3D container “cancel” the 3d transformation.

All of the nested div must have the property transform-style with value as preserve-3d, to preserve the 3D transformation of each of their parent div. It’s automatically defined by Sprite3D.js.
This property doesn’t work currently with IE 11 (nor in previous versions). It flattens 3D transformations in nested DIVs.

Let’s code now!


Quite simple in HTML, with a 2D DIV id="scene3D" where I put the 3D stage inside. It’s not a mandatory DIV, it’s only to make the setup clean and isolate 3D stuffs from 2D elements.
Then, there is a pretty obvious DIV id="page-template". This is the page template used for the targets3DCSS. I’m gonna create 4 targets3DCSS based on this template. Each of them with a different color and displayed name (in the example “Page N”, with N as the page number).


For the beginning, everything is based on a 1280x720px viewport. As well, the size of each elements will be defined in relation to this viewport size. It’s pretty convenient to start like this. I’ll explain in the part 2 why I work in this way. It’s not “mobile first”, but in the last part I’ll show you how make the size of the content flexible and so, make the scene responsive. You’ll chose between fill out the window, keep or crop some areas of your content…

I’ve also created some 3D elements, without Sprite3D.js. These are pretty simple and they don’t need the use of the library. In the case you want to do the same, don’t miss to specify the famous transform-style: preserve-3d;.

The font is available here:


The JS part is based on the gallery example with enhancements for the project specificities. Basically, you add the “Sure Target” logic to the FCameraCSS.

3D Scene

I don’t create a stage + a main container, but instead, a stage + interactive container + main container, all nested. The name for each of them is : stage, interactiveContainer and targetsContainer.
StageCSS is the Sprite3D which contains the whole scene.
TargetsContainerCSS is the container providing the camera behavior. This is the one taking the opposite value of the elements you want to target.
InteractiveContainerCSS provides two features : tweaking the 2D viewport position and use the accelerometer independently of the targetsContainerCSS.

Interpolation function

Quick explanation about the interpolation function. It’s important as everything work on it, in JS and in AE.
This function is driven by the range-input. When the user manipulates the slider, it changes the progress factor value (let’s call it globalCamProgression) and it updates the targetsContainerCSS transformations.
The function takes only one parameter. It’s a string which is the name of the transformation properties you want to interpolate (in this case they are : “x”, “y”, “z”, “rotationX”, “rotationY” and “rotationZ”).

The targetsContainerCSS transformations depends on the targets3D with the nearest ID of the current globalCamProgression value :

  • either globalCamProgression is an integer and you get the target values for the calculation
  • or you get the 2 nearest targets and interpolate linearly their transformation values using globalCamProgression (take a look at to know more)

The function return the opposite number when the calculation is done, in the same principle as the gallery example.

The remaining JS code shouldn’t give any difficulty. The several transformations of stageCSS and interactiveContainerCSS in the createScene() function are the results of tries for cross-browser compatibility.
Temporarily, I feed the scene with randomly placed targets3DCSS. You’ll see later how to change this with AE.

The whole JS file :


Et voilà! You should have a 3D Scene working, pretty close to the gallery example excepted that you control the FCameraCSS from a range-input instead of using a tween engine from one target to another.
Obviously, tweening between 2 targets is still possible and even advised (in the case you want to go from Target 1 to Target 3 and avoid going through Target 2). In our case a linear navigation is required to make it work by swiping the screen.

Click here to see the demo of the current scene:

In the next part of the article, you’ll transpose the actual CSS 3D Scene into AE and I’ll answer some questions such as the relation between focal length and CSS Perspective property.
Ultimately you’ll learn how to create a data exporter for targets3DAE and other 3D elements (like the small white cubes) from AE.


  1. Great post! Question though, since I am not a programmer, what convention would you use if you wanted to do a zoom/pan instead of rotate?

    • Hi Pxlpusher, thanks for your comment!
      Actually if you don’t know CSS nor JS it could be tricky to apply the explanation I guess. The post is more about targeting objects in 3D space and transitioning from one to another than re-creating a real 3D Camera in CSS.

      Anyway, few ideas to answer. To recreate a zoom effect I’d try to work on the z position of the interactiveContainer and workaround the css perspective value at the same time.
      For a panning transformation, rotate around Y axis does the job.
      By positioning camera targets and moving from one to other, you could recreate what you want with no care about the camera itself. I hope it helps! 🙂

Leave a Reply

Your email address will not be published.


© 2018 Turbodrive Blog

Custom theme based on Wilson by Anders NorenUp ↑