前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >浪费了8个小时的摸鱼时间解决z-index不生效问题

浪费了8个小时的摸鱼时间解决z-index不生效问题

原创
作者头像
六边形工程师
修改2024-11-05 08:42:25
修改2024-11-05 08:42:25
2760
举报

1、z-index 的bug出现

近期项目中 ant desgin vuepopup 组件被 “ 标签页 ” 遮挡(如下图), 于是 作为“十年全栈且六边形”的开发人员直接将 z-index 改为了 9999 ,发现竟然不生效,然后浪费了一天摸鱼时间才解决,记录下z-index的一些好玩的问题。

2、问题复现

当遇到这种问题上来肯定F12来看下z-index层级;

第一步,查看下层:标签页 PageTagDivz-index的大小,发现为:3

第二步,查看popupz-index的大小,发现为:1030

神奇的结果:

z-index1030popup组件 竟然被 z-index 层级为 3PageTagDiv 组件 遮挡了!

按照前端z-index原理,数值越大越在上层,不被遮挡,所以就排查吧

3、解决问题第一阶段:position问题

在我的前端技术知识中,有印象 position属性影响 z-index是否生效,于是百度查了下,很多文章有说position属性影响了z-index,摘抄如下:

z-index属性用于控制元素在层叠上下文中的显示顺序。当z-index不起作用时,可能是由于以下几个原因:没有指定元素的定位属性:z-index属性只对定位元素(position属性值为relative、absolute或fixed)起作用。如果元素没有指定定位属性,z-index将不会生效。因此,需要确保元素的position属性已正确设置。 元素的定位属性值不正确:如果元素的定位属性值设置不正确,z-index也不会生效。例如,如果元素的position属性值为static(默认值),则z-index属性将不起作用。需要将元素的position属性值设置为relative、absolute或fixed。 元素的层叠上下文不正确:每个层叠上下文都有自己的层叠水平,z-index只在同一层叠上下文中才有意义。如果元素的z-index属性没有在正确的层叠上下文中设置,它将无法影响其他层叠上下文中的元素。可以通过设置父元素的position属性值为relative、absolute或fixed来创建新的层叠上下文。 元素的z-index值不正确:如果多个元素都具有定位属性且属于同一层叠上下文,那么z-index值较大的元素将覆盖z-index值较小的元素。因此,需要确保所需元素的z-index值较大。总结起来,要使z-index生效,需要确保元素具有正确的定位属性(relative、absolute或fixed),在正确的层叠上下文中,并且具有较大的z-index值。如果仍然无法解决z-index不起作用的问题,可能需要检查其他CSS属性或JavaScript代码是否对元素的显示顺序产生了影响。

于是按照上文给的方案各种修改 position属性,发现并未生效。耗时4小时!

3、解决问题第二阶段:层叠上下文(Stacking Context)

上面文字中有提到 层叠上下文(Stacking Context),我突然有灵感了,以为我有印象 popupPageTagDiv不是一个层级内的,如下图:

红色圈为对应两个组件,他们并不在一个 html根元素中,所以感觉查了下 z-index 层叠上下文(Stacking Context)

3.1、z-index层叠上下文是什么?

MDN官方:假定用户正面向(浏览器)视窗或网页, HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。

The stacking context is a three-dimensional conceptualization of HTML elements along an imaginary z-axis relative to the user, who is assumed to be facing the viewport or the webpage. HTML elements occupy this space in priority order based on element attributes.

每个网页都有一个默认的层叠上下文,这个层叠上下文的根元素就是html元素。html标签中的一切都被置于这个默认的层叠上下文的一个层叠层上(body)。当一个元素创建一个层叠上下文时,它的所有子元素都会受到父元素的层叠顺序影响。这意味着如果一个层叠上下文位于一个最低位置的层,那么其子元素的z-index设置得再大,它都不会出现在其他层叠上下文元素的上面。

3.2、层叠水平与层叠顺序

“层叠水平”,英文称作“stacking level”,在同一层叠上下文中的不同元素重叠时,它们的显示顺序会遵循层叠水平的规则,而z-index能够影响元素的层叠水平。

**重点:在讨论元素基于层叠水平进行排序时,是限制在单个层叠上下文内的。层叠水平不等于z-index属性,所有的元素都存在层叠水平,而z-index属性只能改变定位元素及flex盒子的孩子元素的层叠水平。**

再来说说层叠顺序。“层叠顺序”,英文名为“stacking order”,表示元素发生层叠时候有着特定的垂直显示顺序,这里需要注意,上面的**层叠上下文和层叠水平是概念**,而这里讲到的**层叠顺序则是规则**。

在一个层叠上下文中按照层叠顺序把元素分为7种层叠水平,默认的层叠顺序如下图所示:

解释如下:

  • (1)背景和边框--形成层叠上下文元素的背景和边框。位于层叠上下文中的最底层。
  • (2)负z-index--层叠上下文内z-index值为负的定位元素。
  • (3)块级盒子--层叠上下文中非行内非定位元素。
  • (4)浮动盒子--非定位浮动元素。
  • (5)行内/行内快盒子 -- 层叠上下文中,inline和inline-block非定位元素。
  • (6)z-index:0 /auto -- 定位元素。单纯考虑层叠水平,两者表现一样,但实际上对层叠上下文影响不一样。
  • (7)正z-index值 -- 定位元素。z-index值越大,越靠近用户。

在平时开发时,我们经常会使用(2)、(6)、(7),大部分元素的层叠水平都低于z-index为0的定位元素。

为什么inline/inline-block元素的层叠顺序比浮动元素和块元素都高呢?

因为:border/background一般为装饰属性,而浮动和块元素一般用作布局,内联元素都是内容。网页中展示最重要的是内容,因此内容的层叠顺序比较高,当发生层叠时,重要的文字和图片等内容优先暴露在屏幕上(如下图)。

4、解决问题第三阶段:最终解决

看到z-index上下文以后,终于明白了,因为我的问题中 popupPageTagDiv不是一个层级内的,所以即使z-index1030popup组件大于z-index 层级为 3PageTagDiv 组件,依然会遮挡。

于是目标定位改层级就可以了,查看了下 Ant desgin vue 的 popup官方文档,有个getPopupContainer属性,设置弹出层的容器,这里我设置为返回 body即可,代码如下:

代码语言:js
复制
function getPopupContainer() {

  return document.body;

}

代码地址:高质量代码SmartAdmin:smart-admin-web-javascript/src/layout/components/header-user-space/header-message.vue

这样就在最外层的<body>层级内了,然后问题解决,层级图如下:

解决问题5小时!

5、z-index总结

z-index一定要关注层叠上下文(Stacking Context),即:层叠水平(Stacking Level)与层叠顺序(Stacking Order)都需要关注才能生效。

具体使用技巧总结如下:

  • 第一步:首先先看要比较的两个元素是否处于同一个层叠上下文(Stacking Context)中
  • 1)如果是,谁的层叠等级大,谁在上面
  • 2)如果两个元素不在同一SC中,先比较他们的父SC
  • 当两个元素层叠水平相同、层叠顺序相同时,在 DOM 结构中后面的元素层叠等级在前面元素之上

其他注意事项:

  • CSS3时,无position属性,z-index值也可能生效,因为css3很多默认displayflex
  • 浏览器兼容性差异
  • 避免在transform元素下做fixed定位

6、感想

一个十年全栈就这样被z-index浪费了摸鱼时间的8小时,也应了那句话“活到老,写到老”。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、z-index 的bug出现
  • 2、问题复现
  • 3、解决问题第一阶段:position问题
  • 3、解决问题第二阶段:层叠上下文(Stacking Context)
    • 3.1、z-index层叠上下文是什么?
    • 3.2、层叠水平与层叠顺序
  • 4、解决问题第三阶段:最终解决
  • 5、z-index总结
  • 6、感想
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档