通过设置变换(旋转)取消z-index

时间:2013-12-31 03:52:23

标签: css css3 z-index transform

使用transform属性,z-index被取消并出现在前面。 (当注释掉-webkit-transform时,z-index在下面的代码中正常工作)

.test {
  width: 150px;
  height: 40px;
  margin: 30px;
  line-height: 40px;
  position: relative;
  background: white;
  -webkit-transform: rotate(10deg);
}

.test:after {
  width: 100px;
  height: 35px;
  content: "";
  position: absolute;
  top: 0;
  right: 2px;
  -webkit-box-shadow: 0 5px 5px #999;
  /* Safari and Chrome */
  -webkit-transform: rotate(3deg);
  /* Safari and Chrome */
  transform: rotate(3deg);
  z-index: -1;
}
<html>

<head>
  <title>transform</title>
  <link rel="stylesheet" type="text/css" href="transformtest.css">
</head>

<body>
  <div class="test">z-index is canceled.</div>
</body>

</html>

transform和z-index如何协同工作?

7 个答案:

答案 0 :(得分:111)

让我们来看看正在发生的事情。首先,请注意定位元素上的z-indextransform本身会在元素上创建新的“stacking contexts”。这是正在发生的事情:

您的.test元素transform设置为非空的内容,这为其提供了自己的堆叠上下文。

然后添加.test:after伪元素,该元素是.test的子元素。这个孩子有z-index: -1,在.test:after 的堆叠环境中设置.test 的堆叠级别z-index: -1上的设置.test:after没有将其放在.test后面,因为z-index仅在给定的堆叠环境中具有意义。

当您从-webkit-transform移除.test时,会移除其堆叠上下文,从而导致.test.test:after共享堆叠上下文(<html>)和让.test:after落后于.test。请注意,删除.test的{​​{1}}规则后,您可以再次通过在-webkit-transform上设置新的z-index规则(任何值)为其提供自己的堆叠上下文(再次,因为它的位置)!

那么我们如何解决您的问题?

要让z-index以您期望的方式运行,请确保.test.test共享相同的堆叠上下文。问题是您希望.test:after随变换一起旋转,但这样做意味着创建自己的堆叠上下文。幸运的是,将.test放在包装容器中并旋转它仍然允许其子项共享堆叠上下文,同时还可以旋转它们。

  • 以下是您的开始:http://jsfiddle.net/fH64Q/

  • 这是一种可以绕过堆叠上下文并保持的方法 旋转(注意由于.test的白色背景,阴影有点被切断):

.test
.wrapper {
    -webkit-transform: rotate(10deg);
}
.test {
       width: 150px;
       height: 40px;
       margin: 30px;
       line-height: 40px;
       position: relative;
       background: white;
}
.test:after {
       width: 100px;
       height: 35px;
       content: "";
       position: absolute;
       top: 0;
       right: 2px;
       -webkit-box-shadow: 0 5px 5px #999; /* Safari and Chrome */
       -webkit-transform: rotate(3deg); /* Safari and Chrome */
       transform: rotate(3deg);
       z-index: -1;
}

还有其他方法可以做到这一点,甚至更好的方法。我可能会将“post-it”背景作为包含元素,然后将文本放在里面,这可能是最简单的方法,并会降低你所拥有的复杂性。

结帐this article了解有关<div class="wrapper"> <div class="test">z-index is canceled.</div> </div>和堆叠顺序的详细信息,或the working W3C CSS3 spec on stacking context

答案 1 :(得分:3)

快速修复:您也可以将另一个元素旋转0度。

答案 2 :(得分:0)

我遇到了类似的问题。 我做的是,我在测试周围添加了一个包装div,并将transform属性赋予包装div。

.wrapper{
    transform: rotate(10deg);
}

这里是小提琴http://jsfiddle.net/KmnF2/16/

答案 3 :(得分:0)

将要保留在顶部的div设置为position:relative

答案 4 :(得分:0)

有一个类似的问题,正在transform: translate()同级,而z-index不起作用。

最直接的解决方案是在所有兄弟姐妹上设置position: relative,然后z-index将再次起作用。

答案 5 :(得分:0)

将要保留在顶部的div设置为绝对位置

答案 6 :(得分:0)

对于那些仍在寻找解决方案的人,我找到了这篇文章如何解决 transformz-index here

它的简单用法是这样做:

.parent { transform-style: preserve-3d; }
.parent:before { transform: translateZ(-1em); }