诡异的zIndex

1,049 阅读3分钟

缘起

p1 和 p2 是 fixed 定位的两个父元素,p1 里面包含 c1 子元素 是 absolute 定位,虽然 c1 设置了 zIndex,但是还是被 p2 覆盖了,如下图所示

复现demo

codepen.io/Yangfan2016…

含义

z-index

层叠上下文

如何形成层叠上下文

层叠等级

规则

示例

codesandbox.io/s/keen-mccl…

管理

出现这种问题,主要还是对 zIndex 的认识了解不足,如何更好的正确使用内,下面分为了两种方法:

  • 制定一个项目中使用 zIndex 的规则
  • 动态维护 zIndex

地面派(普通文档流)

不用设置 z-index (即 z-index:auto,不要设置z-index:0,和auto不同,它会创建一个层叠上下文),遵循后来居上

侧边栏(mini页,导航侧边栏,筛选侧边栏)

设置 z-index: 范围 1-10

设置 position:fixed

天空派 (弹框、全局提示)

设置 z-index: 范围 1050-3999

尽量设置 position:fixed 或者挂载到 body 上

顽固派(特殊例子 nps/引导)

设置 z-index: 范围 4000+

设置 position:fixed

实施

  1. 直接将变量定义到 less 或 sass 文件中
// ======= 侧边栏(mini页,导航侧边栏,筛选侧边栏) 范围 1-10 ============

// 基础值
@zindex-sider-base:1;
@zindex-sider-max:10;

// 上面菜单栏
@zindex-sider-top-menu:@zindex-sider-base+1;
// 左侧导航栏
@zindex-sider-left-nav:@zindex-sider-base+2;
// 右侧mini页侧边栏
@zindex-sider-right-mini:@zindex-sider-base+3;
// ... 预留给其他侧边栏

// 下面批量选择操作栏
@zindex-sider-bottom-batch:@zindex-sider-max-1;

// ======= 天空派 (弹框、全局提示) 范围 1050-3999 ============

// 基础值 (rc-trigger 默认值 1050)
@zindex-sky-base:1050;
@zindex-sky-max:3999;

// 弹框
@zindex-sky-modal:@zindex-sky-base;
// 提示框
@zindex-sky-nofice:@zindex-sky-base+1;

// ======= 顽固派(特殊例子) 范围 4000+  ============

// 基础值
@zindex-special-base:4000;
// nps
@zindex-special-nps:@zindex-special-base;
  1. 借助 postcss-css-variables 插件将 变量注入到css文件中
module.exports = {
  // ======= 侧边栏(mini页,导航侧边栏,筛选侧边栏) 范围 1-10 ============
  // 上面菜单栏
  'zindex-sider-top-menu': 2,
  // 左侧导航栏
  'zindex-sider-left-nav': 3,
  // 右侧mini页侧边栏
  'zindex-sider-right-mini': 4,
  // ... 预留给其他侧边栏
  // 下面批量选择操作栏
  'zindex-sider-bottom-batch': 9,
  // ======= 天空派 (弹框、全局提示) 范围 1050-3999 ============
  // 弹框
  'zindex-sky-modal': 1050,
  // 提示框
  'zindex-sky-nofice': 1051,
  // ======= 顽固派(特殊例子) 范围 4000+  ============
  // nps
  'zindex-special-nps': 4000
};
  1. 全局维护 zIndex

参考 element-ui 的源码,如下图,大致的原理是,全局维护了一个 modalStack 存放所有页面上打开过的弹框信息(包含zindex信息),全局维护了一个zindex变量 PopManger.ZIndex

步骤 1. 每打开一个弹框(调用 openModal),zindex自增

步骤 2. 每关闭一个弹框,当前弹框的zindex取自 modalStack 里队尾的zindex值 (modalStack里的值是从小到大排列的,因为步骤1 )

github.com/ElemeFE/ele…

参考

  1. zindex developer.mozilla.org/zh-CN/docs/…
  2. zindex drafts.csswg.org/css2/#propd…
  3. 层叠上下文 developer.mozilla.org/zh-CN/docs/…
  4. 为什么z-index不好使了?记录一下我对层叠上下文的理解  juejin.cn/post/684490…
  5. 搞懂Z-index的所有细节  zhuanlan.zhihu.com/p/26866325