Css z-index 丢失后,webkit 转换 tranate3d

我有两个绝对定位的 div 元素,它们是重叠的。它们都通过 css 设置 z-index 值。我使用 translate3d webkit 转换将这些元素从屏幕上动画化,然后再回到屏幕上。转换之后,元素不再尊重它们设置的 z-index值。

有人能解释一下在对 div 元素进行 webkit 转换之后,它们的 z-index/stack-order 会发生什么变化吗?并解释如何保持 div 元素的堆栈顺序?

下面是关于如何进行转换的更多信息。

在转换之前,每个元素通过 css 获得这两个 webkit 转换值(我使用 jQuery 来执行 .css()函数调用:

element.css({ '-webkit-transition-duration': duration + 's' });
element.css({ '-webkit-transition-property': '-webkit-transform' });

然后使用 transate3d-webkit-change 对元素进行动画处理:

element.css({ '-webkit-transform': 'translate3d(' + hwDelta + 'px, 0, -1px)' });

顺便说一下,我曾经尝试将 translate3d的第3个参数设置为几个不同的值来尝试在3d 空间中复制堆栈顺序,但是没有成功。

此外,iPhone/iPad 和 Android 浏览器是我的目标浏览器,这个代码需要运行。

101737 次浏览

Waiting to see the example

Have you tried to do a transform scale(1)? I remember to had a similar problem, and I had to re-arrange the html order of elements, and utilise a transform that I didn't need it just because the z-index of the use of transform changed.

If I am not in error, every time that you use a transform, it become the highest z-index available, and it is ordered by the nearest element of html is to the start of the tag. So from up to below.

I hope that this help

I haven't been able to reproduce the problem you describe here. Regardless of what I do, the z-index value is retained throughout all transforms. I'm testing using Chromium (Google Chrome).

The third argument of the translate3d function manipulates the z-axis of the element. The concept is similar to, but not exactly the same as, the z-index... Elements with a lower z-axis are under elements with a higher value.

I know you tried values of the third argument to match your intended z-index, but the problem is that the z-axis doesn't seem to change during CSS3 animation. In the following example, the hovered element should be on top, but #element_a stays on top.

If I add a z-index to both the regular selector and the :hover selector, it seems to work and allow the hovered element to be top-most.

Although it's not exactly what you were looking for, this behavior provides a solution. You just need to use translate3d and z-index to set the order for the initial rendering.

<style>
div {
width: 300px;
height: 150px;
background-color: white;
border: 5px outset gray;
float: left;
margin: 20px;
-webkit-transition: 2s;
}


#element_a {
-webkit-transform: translate3d(0, 0, 50px);
}
#element_b {
-webkit-transform: translate3d(0, 0, 100px);
}


#element_a:hover {
-webkit-transform: translate3d(100px, 0, 60px);
}


#element_b:hover {
-webkit-transform: translate3d(-100px, 0, -60px);
}
</style>
<body>
<div id="element_a">
<img src="http://www.google.com/intl/en_com/images/srpr/logo3w.png">
</div>
<div id="element_b">
<img src="http://www.google.com/intl/en_com/images/srpr/logo3w.png">
</div>
</body>

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;.

This is most definitely related to the bug noted by samy-delux. This should only affect any elements which are positioned as absolute or relative. In order to remedy the issue, you can apply the following css statement to every element which is positioned this way and is causing issues:

-webkit-transform: translate3d(0,0,0);

This will apply the transform to the element without actually doing a transformation, but affecting its render order so it is above the element causing the issue.

z-index will work against 3d transformed divs if you style the stackable element with -webkit-transform: translateZ(0px);

Snippet on codepen -> http://codepen.io/mrmoje/pen/yLIul

In the example, the buttons stack up and stack down raise and lower the footer's z-index (+/-1) against the rotated element (an img in this case).

Bit Late to this but try putting on the elements that have lost their Z-index placing the following, I had an issue when doing some parallax stuff recently and this helped massively.

transform-style: preserve-3d;

This saves putting

transform: translate3d(0,0,0);

On other elements which puts more strain on the GPU

Another way around this is that you can create a parent element and apply all other transitions related to it:

# Apply transitions to a parent div
<div>
# This image z-index -1
<img src="foo"/>


# This image z-index -3
<img src="bar"/>


#This image z-index -2
<img src="gg"/>
</div>

JsFiddle

I had this problem on iphone/ios where I had a dropdown menu that overlapped a leafletjs map but was being covered by the map. Noticed that the map had translate3d applied.

Added this to the dropdown element:

transform: translate3d(0,0,0);

...and it is fixed. Thank you stackoverflow people.