3D in the Browser: WebGL versus CSS 3D Transforms

Making The Web Faster With SPDY

WebGL and CSS 3D transforms are two major technologies for creating 3D in the browser, and as recently as a few years ago, they didn’t have much browser support. Much has changed in a short period of time, and if you haven’t given 3D much attention (like me), you might have more catching up to do than you realize. The more recent versions of Internet Explorer support 3D transforms and the upcoming version (IE11) will support WebGL. My guess is that major browser support along with some kind of backlash to flat design could create the right conditions for 3D technology to flourish. Whether or not that happens, it’s a good idea to at least be familiarized with what’s already out there. The following is a high level summary of my research that should help get you started.

CSS 3D Transforms

The general sentiment behind 3D in the DOM makes sense. HTML describes structure and CSS 3D transforms describe visual presentation. As long as this relationship is respected, it’s a pretty logical path to walk. I’m not going to go into the details of 3D transform properties here, but you can learn more about them in the Treehouse course CSS Foundations. Instead, I’d rather give you a quick tour of some of my own exploits along with a few interesting projects you should watch.

Shading and Multiplaning

On the blog Codrops I wrote a guest article about a technique I call 3D shading with box-shadows. This is my most recent exploration into DOM-based 3D and I’m happy with it because it’s a bit more semantic than some of my other attempts. Previous to that, I posted on the Treehouse Blog about a technique I call multiplane design. The idea is that by adjusting the relative distances of flat 2D planes along the Z axis, you can create the illusion of 3D depth. Here’s a diagram from the post that should help explain: Illustration of the 4 planes broken apart in layers. Even more recently, a JavaScript project called parallax.js implemented an idea with a similar spirit. Instead of multiplaning along the Z axis, they move their planes along the X and Y axes, which creates a wonderful illusion of deep space.

Modeling Objects

Around the same time, a 3D CSS editor called Tridiv was released. It behaves much like a traditional 3D modelling application on the desktop with several tools for manipulating objects and camera position. The resulting code can be pasted into your website quite easily, and they even allow you to edit the code on CodePen with the click of a button. For completeness, I’d like to mention that Tridiv utilizes a lighting engine called Photon, which is also an interesting project.

Creating Worlds

Finally, you should check out this amazing article from earlier this year called creating 3D worlds with HTML and CSS by Keith Clark. In the article, Keith describes some of the most advanced CSS 3D techniques I’ve ever seen. He even went so far as to write his own lighting engine and generate a height map for a player character to navigate multiple levels of terrain.

WebGL

The more advanced of the two technologies is WebGL. It has a much higher learning curve and can be difficult to grasp for beginners. If you’re new to 3D in the browser, I recommend you try using CSS 3D transforms first. Also, I found this talk from Steven Wittens at JSConfUS 2013 to be quite a good primer on 3D graphics: WebGL is unlike HTML and CSS in that it’s rendered onto a <canvas> element, so rather than being a pervasive feature of the document structure, it’s isolated to a specific context. This sounds like a big downside, but because the canvas is itself a DOM element, a lot of flexibility can be retained.

Three.js

One of the most important projects in WebGL right now is three.js - it actually has renderers for canvas and SVG as well, but the WebGL renderer is great because it lowers the barrier to entry for WebGL. Three.js provides APIs for renderers, shaders, cameras, lighting, scenes, effects, and much more. There’s also a vibrant community creating demos and tutorials to help you get started.

Voodoo.js

Another one of my favorite projects is Voodoo.js because it allows you to overcome some of the shortcomings of using the canvas element. Using some clever code (that some might even call voodoo) you can mix WebGL contexts with normal HTML. Click through to the Voodoo website and then scroll down the page to see the cool parallax effects. You might also want to try highlighting the quote at the bottom of the page that has the golden ring around it. It’s just HTML text, but it magically has a WebGL ring floating around it. Pretty impressive. "The art challenges the technology, and the technology inspires the art." - John Lasseter

chrome Experiments

If you’re still not impressed, you should definitely check out the WebGL Chrome Experiments. All of them are pretty amazing and you’ll get to see the range of what WebGL has to offer. One of the best I’ve seen is the Delight Engine demo which features some advanced real-time lighting effects I haven’t seen anywhere outside of top-tier AAA video game titles.

OK, so which 3D is the best 3D?

Recently, Acko.net got a WebGL redesign (this is the website of Steven Wittens, the guy in the JSConf talk embedded above). Steven talks about the redesign in an article called Zero to Sixty in One Second, and he said something that I can’t help but agree with:

…the DOM is not a good place to store complicated geometry.

I hate picking sides, and I really don’t want to take anything away from Tridiv, parallax.js, or even my own experiments in multiplaning. However, I don’t think it’s a good idea to muddle beautifully semantic HTML with elements that only exist to be polygonal faces. Maybe the CSS shapes module will change this somewhat, but right now you can only create rectangular faces. Some CSS hacks will get you a little further and allow you to create triangular and circular faces, but it’s still less than ideal. HTML is still decent for simple geometry, such as in my box-shadow shading example where each element has some sort of information inside. I just don’t think we should be building complex 3D models with div elements. Once a model reaches a certain level of non-semantic ugliness, it’s time to consider upgrading to WebGL. The limitations of WebGL can be overcome, and I think carefully weaving it into the DOM is a worthwhile pursuit. Voodoo.js does a great job of this and I only suspect this type of trend will continue. The redesign of Acko.net is another awesome example of how WebGL can coexist, unlike other technologies that are aliens in the browser (namely, Flash).

Designing with 3D

For some of you, the visual cool factor and technical wizardry isn’t enough. If you’re like me, you want to know what 3D can do in a practical setting. Right now, I’m really not sure what the future holds for 3D in the browser. Acko.net is a cool concept, but I don’t think it’s going to inspire everyone to run off and create their own 3D header. Will 3D be confined to the realm of games and demos? Does it belong within the context of building utilitarian web applications? Can such a label ever be applied, and does it matter?

Nick Pettit

Nick is a designer, public speaker, and teacher at Treehouse. He is also a co-host of The Treehouse Show. Twitter: @nickrp

Comments

6 comments on “3D in the Browser: WebGL versus CSS 3D Transforms

  1. For dealing with more complicated shapes: how about constructing the shapes as SVG documents with transparent backgrounds and then using CSS transforms to move them off the plane and into the desired position?

    • Possible, but still not super awesome, because you’ll still need a DOM element container for each SVG. DOM elements can be somewhat costly in high numbers, especially when you need one for every face.

      Models in WebGL, particularly those stored in JSON, are far less memory intensive and, on decent hardware, can get you up around a million triangles with good framerates. To do that in the DOM would crash the browser.

  2. I have a question Nick.

    How do we stop the Parent or Body Div’s collapsing when using these 3D tools? Sometimes I find this causes some problems. I’m pretty sure it is the CSS Transform that does it I think.

    I don’t have any examples, but I hope you have come across this.

    • In many cases you have to set an explicit width and height on your container elements, then position them using absolute positioning. After that, the real positioning can be done with translations on the XYZ axes. Similar techniques are common for both DOM and WebGL based 3D.