While exploring the possibilities of 3D CSS transformations, we ran into an interesting limitation (bug?) in Firefox. We were building an experiment that takes a heightmap and converts it into a 3D terrain. It turns out that Firefox chokes when the number of elements in the 3D animation exceeds about 80, and that overlapping elements […]
This article was posted by Independent Software, a website and database application development company based in Maputo, Mozambique. Our website offers regular write-ups on technical and design issues, ranging from details at code level to 3D Studio Max rendering. Read more about Independent Software's philosophy, or get in touch with Independent Software.
While exploring the possibilities of 3D CSS transformations, we ran into an interesting limitation (bug?) in Firefox. We were building an experiment that takes a heightmap and converts it into a 3D terrain. It turns out that Firefox chokes when the number of elements in the 3D animation exceeds about 80, and that overlapping elements cause flickering.
In this project, we take a small 10×10 grayscale heightmap and turn it into a 3D landscape using pure CSS.
A bit of PHP code loads this image and generates a series of cubes, each consisting of five <div> elements: a top and four sides. These cubes are then positioned in a grid and scaled along the Y-axis to create the correct heights, producing this (screenshot from Chrome browser):
Here is the experiment on Codepen (which should work correctly in Chrome but not in Firefox):
Since the cubes have four sides, the terrain can then be nicely rotated around its Y-axis. All of this works well in Chrome, but not in Firefox (version 49.0.1). For starters, Chrome performs much better, but that’s not the biggest problem. There are two other problems that are much worse:
1. Firefox chokes on 80+ elements
Everything works well in Firefox for terrains up to 4×4 cubes, or 80 <div> elements. Beyond that, as the terrain rotates, the Z-order of the cube sides breaks and this happens:
Here, the back sides of the cubes (jn brown) break through the tops surfaces of the cubes (in green). No amount of fiddling with the CSS fixes this, short of reducing the number of cubes.
2. Firefox does not like overlapping divs
Since the cubes are stacked one against the other, one cube’s side touches (overlaps) the other’s in 3D space. Although CSS backface-visibility is hidden , and all sides are rotated correctly so that they face outward from the cube, one two elements occupy the same space, they will flicker and break the Z-order. The only way to fix this is the make the cubes actually smaller. Originally, all cubes have dimensions of 1em x 1em, but once reduced to 0.9em x 0.9em, the flicker will go away, but at the cost of a noticeable gap between the cubes.
Adding borders to the faces aggravates the problem, but this is to be expected as added borders actually makes the sides larger. Adding box-sizing: border-box does not appear to help.