美文网首页
transform && z-index

transform && z-index

作者: CC前端手记 | 来源:发表于2020-06-24 12:03 被阅读0次

    今天遇到一个问题,就是使用了transform属性的元素,其子元素的z-index属性失效了。网上搜了很多信息,大致了解了这个问题的来龙去脉,来跟大家分享一波。

    我们都知道,z-index可以通过设置数值大小,来决定层级高低,但一涉及transform,z-index就失效了,为什么呢?

    一、原因

    原来,web中的任何元素都存在于一个三维空间中,除了大家熟知的平面画布中的x轴和y轴之外,还有控制第三维度的z轴。元素在x轴和y轴上的表现,可以使用margin、float、offset这些属性来控制。而z轴上的表现,则可以通过z-index和transform等属性来控制。

    z-index控制z轴,需要配合position属性,z-index的数值越大层级就越高。transform可以通过它的translateZ() 来改变元素的层叠顺序,值越大则层级越高。不过通过transform:translateZ() 改变元素z轴层级,必须在其父元素中设置transform-style:preserver-3d 或者在transform中设置perspective() 才有效。

    有人可能会问,如果二者同时设置会怎样呢?原来,transform会创建比z-index更高层级的stacking context(堆叠上下文),所以z-index会失效。

    二、堆叠上下文

    css是层叠样式表,层叠上下文就是html文件渲染的时候,各个元素的堆叠规则,哪个元素在距离屏幕更近的层级,类似Photoshop中的图层原理,这也是css中非常重要的潜在规则。

    所以,给元素设置transform属性会创建层叠上下文的一个新区域,原本的层叠规则就会发生变化,设置transform的元素就变成了一个层叠上下文容器,也就相当于处于最底层了。此时,它的子元素如果需要被点击,可能就会受到影响了。当然,它的兄弟元素或其他外层元素的层叠规则并不受影响。

    三、创建新区域的方法

    除了transform之外,还有哪些情况会创建新的区域呢?

    • 根元素(HTML)
    • 设置了position为absolute或relative,且z-index不是auto的元素
    • 设置了z-index,且不为auto的流动元素
    • 设置了opacity,且不为1的元素
    • 设置了transform,且不为none的元素
    • 设置了mix-blend-mode值,且不为normal的元素
    • 设置了isolation 为 isolate的元素on mobile WebKit and Chrome 22+,
    • 设置position为fixed的元素

    四、解决方案

    1. 避免使用transform属性,改为使用margin-left:(-width/2)属性来实现元素居中;
    2. 给使用transform元素的父级增加transform-style: preserve-3d;
    3. 给使用了transform元素显示的设置perspective()
    4. 元素里再创建一个标签,应用新标签的before伪类,设置定位,以原来的元素为基准,top、bottom、right、left为0,以充满整个容器。注意,z-index的设置与原来元素的before、after中的z-index有关,必须比它的值大。
    5. 使用pointer-events属性做穿透处理。

    我的项目使用前几种方法都无效,最后尝试穿透处理就ok了。你遇到的问题呢?

    相关文章

      网友评论

          本文标题:transform && z-index

          本文链接:https://www.haomeiwen.com/subject/dcrffktx.html