CSS3 Transform: Translate3D Doesn't Affect The Z-Axis

CSS3 transform: translate3d doesn't affect the z-axis?

Got it. Forgot to add -webkit-transform-style: preserve-3d;

css z-index lost after webkit transform translate3d

This might be related to: https://bugs.webkit.org/show_bug.cgi?id=61824

Basically when you apply a 3D transform on the z-axis, the z-index can't be accounted for anymore (you're now in a 3 dimensional rendering plane, use different z-values). If you want to switch back to 2D rendering for child elements, use transform-style: flat;.

Can't make translate3d Z property to work

I was missing -webkit-perspective parameter on the parent element. When I added this it started working just like it should.

CSS transform interferes with z-index

It's because your popup is INSIDE another div which has default z-index. It has nothing to do with the transformation.

Like Jonathan Sampson said

You can't give a child higher z-index than its parent.

Simple as that.

There're few solutions possible and you should choose what fits your needs.

  • Put your popup outside its div. So its z-index doesn't depends on the parent anymore.
  • Give to the red box a different z-index ( higher than the other red box) - Example

CSS performance relative to translateZ(0)

CSS transformations create a new stacking context and containing block, as described in the spec. In plain English, this means that fixed position elements with a transformation applied to them will act more like absolutely positioned elements, and z-index values are likely to get screwed with.

If you take a look at this demo, you'll see what I mean. The second div has a transformation applied to it, meaning that it creates a new stacking context, and the pseudo elements are stacked on top rather than below.

So basically, don't do that. Apply a 3D transformation only when you need the optimization. -webkit-font-smoothing: antialiased; is another way to tap into 3D acceleration without creating these problems, but it only works in Safari.

perspective and translateZ moves diagonally

It's all a matter of perspective-origin that define how the changes should be visible to us.

If you read the same link you will notice this:

The vanishing point is by default placed at the center of the element, but its position can be changed using the perspective-origin property.

Here is some example where you can better understand:

.wrapper {  position: relative;  height: 100px;  width: 100px;  border: 1px solid;  perspective: 10px;  transform-style: preserve-3d;}
.cube { width: 100%; height: 100%; background: red; animation: change 2s linear infinite alternate;}
@keyframes change { to { transform: translateZ(-10px); }}
moving from the center<div class="wrapper">  <div class="cube"></div></div>moving from the left<div class="wrapper" style="perspective-origin:left">  <div class="cube"></div></div>moving from a custom point<div class="wrapper" style="perspective-origin:20% 80%">  <div class="cube"></div></div>

z-index is canceled by setting transform(rotate)

Let's walk through what is occurring. To start, note that z-index on positioned elements and transform by itself create new "stacking contexts" on elements. Here's what's going on:

Your .test element has transform set to something other than none, which gives it its own stacking context.

You then add a .test:after pseudo-element, which is a child of .test. This child has z-index: -1, setting the stack level of .test:after within the stacking context of .test Setting z-index: -1 on .test:after does not place it behind .test because z-index only has meaning within a given stacking context.

When you remove -webkit-transform from .test it removes its stacking context, causing .test and .test:after to share a stacking context (that of <html>) and making .test:after go behind .test. Note that after removing .test's -webkit-transform rule you can, once again, give it its own stacking context by setting a new z-index rule (any value) on .test (again, because it is positioned)!

So how do we solve your problem?

To get z-index working the way you expect, make sure that .test and .test:after share the same stacking context. The problem is that you want .test rotated with transform, but to do so means creating its own stacking context. Fortunately, placing .test in a wrapping container and rotating that will still allow its children to share a stacking context while also rotating both.

  • Here's what you started with: http://jsfiddle.net/fH64Q/

  • And here's a way you can get around the stacking-contexts and keep
    the rotation (note that the shadow gets a bit cut off because of .test's white background):