Friday, August 29, 2014

Chrome rendering quirk when using 3D transforms

In Chrome 36.0.1985.143 I encountered a fascinating rendering quirk related to some elements that had a 3D transform and perspective. Firefox didn't exhibit the behavior. Baffled at first, I finally figured out what Chrome is doing.

Check out this layout where I've reproduced the problem. Try clicking the yellow box:

Notice that, even though the blue content box appears on top of the gray rectangle, you can only click on the yellow box over the word "me" where the gray box has ended.

Firefox lets you click the whole box as expected; but in Chrome, only a part.

I tried shifting the gray box by changing the left CSS property,wherever the gray box was, I couldn't click. ... until the gray box was shifted far over to the right:

Odd. Then I found a shift where I could only click half of it again (over the word "Click"):

Notice that you can only click the other side of the yellow box now, even though the gray box is entirely "behind" the yellow one.

So what's happening?

Chrome is rendering the z-index properly, but z-index does not apply to 3D transforms. The gray box was rotated on the Y axis so that, on the left, it's further away from the user on the Z axis, but on the right, it is closer to the user -- so close, in fact, that it is cutting through the yellow box, even though it does not appear this way visually.

This could be argued as an edge case, but it is a very real concern for web developers using 3D transforms in their layouts. The work-around is to use another 3D transform, translateZ, instead:

By translating the content on the Z axis toward the user enough so that it appears in front of even the gray element's right side, the entire content area is selectable and clickable again.

To see this even more clearly, try changing the translateZ value on #content to 90px instead of 100px in that last fiddle, and you'll see that only a small part of the yellow box is not clickable. That part is still considered as "behind" the gray box in Chrome's surface map.

I hope that made sense. This had me scratching my head for a few minutes. Firefox exhibited the behavior I expected, but Chrome was technically more correct in rendering the surface map in a 3D space. Now I'm not sure what to think.