February 13, 2012 5

3D transformations with Firefox 10+

By

Firefox 10 was released toward the end of January and added support for 3D transforms. Here are some lessons learned whilst ensuring Flux Slider worked with Firefox.

There are some definite differences between the Firefox & WebKit implementation of 3D transforms, I’m not familiar enough with the details of the spec to know which is “correct” but I’ve outlined what I’ve found.

Perspective doesn’t propagate

In a WebKit browser, when perspective is applied to an element the effect propagates to all child elements irrespective of depth. In Firefox it appears that the effect is only applied to the elements direct child elements.

JSFiddle Example

Update: You can work around this issue in Firefox by adding -moz-transform-style: preserve-3d at each depth, JSFiddle Example. Thanks to Gustaff Weldon & Bartek Szopka for the fix.

Update: There is a ticket in the Mozilla bug tracker for this already: Bug 716524. Thanks to Rob Hawkes for finding this.

Perspective origin doesn’t work the same

The perspective-origin CSS property determines the position the viewer is looking at. It is used as the vanishing point (abscissa) by the perspective property. (MDN)

I use this property in the bars3D transition in Flux and the desired effect is that all the “slices” created, and subsequently rotated, have a common vanishing point.

In WebKit if you apply perspective and perspective-origin on an element then all child elements calculate the vanishing point based on the vanishing point for that element.

In Firefox however the perspective-origin property seems to be inherited by child elements and the value calculated for each element. For example if perspective-origin property is set to 50% 50% then instead of the vanishing point for each child being the parents centre, they become the centre of each element.

JSFiddle Example

Update: Thanks again to Bartek Szopka for another fix. Instead of using -moz-perspective: 500 you can use -moz-transform: perspective(500px) along with -moz-transform-style: preserve-3d to work around this, JSFiddle Example.

Don’t mix z-index with 3D transforms

When Chrome added support for 3D transforms it was sometimes needed to add z-index values to help it correctly stack layers in 3D space. Firefox however appears to behave quite erratically when you mix 3D transforms with z-index.

The most repeatable example is that backface-visibilty appears to be ignored when z-index is applied.

JSFiddle Example

Detecting 3D transform support

The Media Query technique Modernizr uses to detect 3D transform support in WebKit doesn’t work in Firefox. Instead you can just check for the existance of the MozPerspective CSS property:

'MozPerspective' in document.body.style

Update: To prevent confusion, Modernizr correctly identifies 3D transform support for Firefox 10 by using a combination of the two techniques above (apologies if it sounded like I was suggesting otherwise). If like me you need to support a library that isn’t dependant on Modernizr then you’ll need to add the perspective check to your detection code. Here is the code Flux uses.

Still no matrix object

There is still no MozCSSMatrix object to replicate the functionality of the WebKitCSSMatrix object. This means that there are a still a lot of cool things you can do with JavaScript & transforms in WebKit that you can’t in Firefox (e.g. Morf.js);

  • Pingback: Flux Slider v1.4.3 Released » Joe Lambert

  • bartaz

    I’ve seen most of these issues during my Firefox tests of impress.js.

    It seems that spec is not very clear in some points, so it’s quite hard to say which implementation is ‘correct’.

    Webkit’s seems more ‘natural’ – especially when it comes single vanishing point of perspective origin. But spec doesn’t seem to say anything about it.

    And then it comes to ‘propagating’ perspective. Again it seems to work ‘better’ in webkit, but Firefox’s implementation is also in line with spec when it comes to transform-style. Transform-style only affects direct children, so when it’s not specified to ‘preserve-3d’ it defaults to ‘flat’ – that’s why the perspective ‘disappears’ when there are more levels of elements. Putting ‘preserve-3d’ on every level fix the issue.

    (I can even add one issue to the list – perspective doesn’t work at all in Firefox on elements with overflow: hidden – but that’s obviously a bug, and I’ve seen it reported on their bug tracker).

  • http://www.joelambert.co.uk Joe Lambert

    Thanks for the info, I’ll update the post with details of your workaround.

    I agree that not having to add preserve-3d to every element feels more natural but I think some of these issues need to be addressed in the spec so that there isn’t the ambiguity!

  • Pingback: New issue with 3D Transforms in Firefox 11 » Joe Lambert

  • Pingback: HTML5 Weekly No.25 | ENUE Blog