Dynamic 3D with CSS and the DOM

Published: 4th August 2006

Nearly six years ago, when I was in the early days of my web career, I embarked on a personal project to build a 3D dungeon environment for a JavaScript game. My skills and knowledge were both in their infancy, and since I didn't know any better, I created the perspective views using images.

A 3D drawing of an underground corridor, with several corridors branching off to the right,
					shown from the 1st-person persective. The visual result was not too bad - the perspective is reasonably accurate, if a little too tall; but there's no depth or shading to the walls, so the sense of 3D is conveyed by the perspective lines alone. But the real problem was how laborious it was to program: each view is comprised of about a dozen vertical stripes, each of which contains an image, and for each point on the map and each direction of that point, I had to manually work out which images go together to make that particular view! Extremely tedious and time-consuming work, and so it was impractical to create very large dungeon areas to play in.

The game worked okay (in IE5!) and I was still proud of what I'd made, but pretty soon I'd forgotten about it, and moved onto pastures new.

But then one day...

Turn the clock forwards to 2006, and for no particular reason, I remembered all this. Pretty soon my mind had come round to wondering whether it could be re-done, without using images or vector formats, use Tantek's technique of creating shapes out of the interaction of CSS borders.

The principle is very simple (examples are images, not code):

Figure 1
If an element has a very thick border (say, 50 pixels), and co-inciding borders are different colors (say, red on the left and blue on the top), then the intersection of those borders creates a diagonal line (fig1).
Figure 2
By varying the relative border-widths, different angles can be created; and by using "transparent" as one of the border colors, the diagonals can run against transparency (fig2).
Figure 3
So finally, wrapping another element around the first, and then using CSS clip on the outer element so that only a corner of the inner element is exposed, we can effectively create a right-angled triangle of any size, with a choice of four orientations (depending on the outer clip), and with transparency on all three sides (fig3).

Once we can do that, it's simply a case of working out how many to make and where to position them, and then we can indeed create 3D perspective drawings using CSS alone! But of course that's still a lot of calculation - nobody wants to sit there working out the lines involved in all those different views - so in steps the DOM!

Another 3D drawing of an underground corridor, an identical view to the previous,
				but here the depth and sense of 3D is more realistic. And with a little math and some judicious JavaScript, we can end up producing something much better than the original: the wall slices are computed on the fly to give a far more accurate and controllable perspective, colors are progressively shaded to give a better sense of depth, and the bordering onto transparency allows for image textures to be used to make attractive floors and ceilings.

And all done without tedium! The viewer's input data is a 2D dungeon floor plan, and each 3D view is created on demand. This makes it quick and easy to create very large dungeon areas, and also means that details of the visual output - such as the shading and depth of perspective - can be edited and fine-tuned over time.

So where do we go from here?

Right now, the answer is nowhere - I have too many other things to do!

But longer term there are neat possibilities to explore: a gaming framework for puzzles, challenges and combat among multiple players; an AJAX-powered online environment; perhaps an API so that users can design and host dungeons themselves. It should even be possible to build a text-transcoder, to make the game more accessible by dynamically creating a description of each view.

And of course, what's already there still needs some work! The shading algorithms aren't quite right, and there are rounding errors in the output, particularly evident towards the end of a long corridor.

But in the meantime, if you feel like developing this further, or if anything I've done here is useful to you - be my guest (smile)

Get the files

Get the files

BSD License → Terms of use

Featured in...

The Art & Science of JavaScript Seven of the greatest minds in modern JavaScript teach you the most inspirational techniques you'll ever use. More info | Buy this book!


Ideas and prototypes

Some nebulous thoughts and unfinished projects:

  • Dynamic 3D with CSS and the DOM [this page]

Browsers and devices

Web development tips and information for specific devices:

Our internal search engine is currently offline, undergoing some configuration changes in preparation for a major site overhaul. In the meantime, you can still search this site using Google Custom Search.

In this area

Main areas

[brothercake] a round peg in a square hole, that still fits