📖
blog
  • README
  • JavaScript
    • 元素的宽高位置信息梳理
    • dom-align 源码浅析
    • Event Loop
    • 函数实参为对象时的陷阱
    • export 与 utils 方法书写规范
    • 手写 Promise 及相关代码理解
    • call,apply,bind 等函数的模拟实现
    • JavaScript继承
    • JavaScript 数据类型与类型判断
    • for..of 和 for..in 的区别
    • 写给自己看的 next 函数
    • JS 可选链与双问号
    • mouseenter 与 mouseover 事件的区别
    • Immutable相关知识
  • CSS
    • 不简单的 z-index
    • 两列布局,三列布局
    • CSS 居中方案整理
    • CSS 像素,设备像素,2倍图梳理
    • iconfont 的使用
  • Node JS
    • 实现简易的 express
  • React 核心知识点整理
    • 高阶组件
    • React 事件处理
    • React Hooks
    • React Context
  • React 状态管理
    • Redux 基础概念
    • Redux 中间件和异步操作
    • Redux Saga
    • Redux 只能有一个 store 对象嘛
  • React 开发实践
    • Ant Design Menu 组件的使用与深入
    • 讲讲吸顶效果与 react sticky
    • 基于 express,搭建 react 的开发环境
    • 通过 antd input 组件分析受控与非受控组件
    • DebounceClick 组件
    • react component Align 组件分析
    • React Portal 之事件冒泡
    • React Transition Group 源码浅析
    • React.cloneElement 父组件向子组件注入 props
    • 一次 Align 组件的问题记录
    • 如何知道子组件的类型
    • React Router 源码简单分析
    • React Redux 源码简单分析
  • Vue.js
    • Vue.js 概览
    • scoped 样式中的 deep
  • TypeScript 语法
    • 基础类型
    • 变量声明
    • 接口
    • 类
    • 函数
    • 泛型
    • 枚举
    • 类型推论
    • 类型兼容性
    • 高级类型
    • Symbol
    • 迭代器和生成器
    • 模块
    • 命名空间
    • JSX
  • 玩转 webpack
    • 第一章: webpack 与构建发展简史
    • 第二章:webpack基础用法
    • 第三章:webpack进阶用法
    • 第四章:编写可维护的 webpack 构建配置
    • 第五章:webpack构建速度和体积优化策略
    • 第六章:通过源代码掌握webpack打包原理
    • 第七章:编写Loader和插件
  • webpack 实践
    • 如何配置 output.library
  • 测试
    • 初识代码测试
    • Jest 中 如何测试 setTimeout
    • Jest Enzyme React 测试实践记录
  • WEB 开发,过往工作沉淀
    • Web安全(DVWA)
    • 内存泄露与事件移除的必要性
    • url to pdf api 与 服务部署踩坑记录
    • 前端调试指南
    • Markdown 转 email
    • github travis ci 自动部署
    • 浏览器缓存知识梳理
    • WEB 系统登录相关知识梳理
    • 将-Axios-请求参数和返回值进行格式化
    • source-map与源码调试
    • HTTPS
    • 使用 rollup 打造自己的 npm 包 (全流程)
    • father-build 是如何工作的
  • 书籍
    • 图解 HTTP 协议
    • 编写可维护的 JavaScript
    • 鸟哥的 Linux 私房菜
    • JavaScript Promise迷你书
  • Linux
    • vimtutor
    • CURL 使用指南
  • Nginx
    • 一次 nginx 分享
  • Git
    • Git Commit Message 须知
    • .gitignore 模板
    • git tag标签
  • 摄影
    • 摄影基础知识
    • 手机摄影从小白到大师
  • 翻译
    • log4js
    • log4js-node
    • 介绍GitLab上的CI/CD
    • 为GitLab Pages创建并调整GitLab CI/CD
    • 关于 rel=noopener
    • AngularJS 团队 Git 提交信息约定
    • JSON Schema
  • Lifehack
    • 20 个 Google 搜索 Tips 来高效使用 Google
    • 37 个高级 Google 搜索 Tips
Powered by GitBook
On this page
  • 1. 关键概念
  • 1.1 层叠顺序
  • 1.2 形成层叠上下文的因素
  • 2. MDN文档分析
  • 2.1 Stacking without z-index
  • 2.2 堆叠与浮动
  • 2.3 Adding z-index
  • 2.4 层叠上下文
  • 2.5 Stacking context example 1
  • 2.6 Stacking context example 2
  • 2.7 Stacking context example 3
  • 2.8 没人告诉你关于z-index的一些事
  • 2.9 antd中的弹窗类组件
  • 3. 参考资料及疑问

Was this helpful?

  1. CSS

不简单的 z-index

1. 关键概念

1.1 层叠顺序

层叠顺序,即在同一层叠上下文中的排序规则:

  1. 形成层叠上下文的背景和边框

  2. 定位 的带有 负值 z-index 的元素,该元素形成 子的层叠上下文

  3. 非定位 的块级元素

  4. 非定位 的 浮动 元素

  5. 非定位 的行内元素

  6. 定位 的 z-index 为 0或者auto 元素

  7. 定位 的 z-index 大于 0 元素

同一层叠顺序按照在HTML中出现的顺序层叠

1.2 形成层叠上下文的因素

  1. 根元素html

  2. 相对,绝对定位元素,且z-index不为auto

  3. position:fixed的元素,不关心z-index的值

  4. z-index不为auto 的flex项目,即父元素为display:flex|inline-flex

  5. opacity小于1

  6. transform 属性值不为none

  7. mix-blend-mode属性值不为normal的元素

  8. filter值不为none的元素

  9. perspective值不为none的元素

  10. isolation值为isolate的元素

  11. will-change中指定任意css属性

  12. -webkit-overflow-scrolling属性值为touch的元素

子元素的z-index值只在父级层叠上下文中有意义。没有创建自己层叠上下文的元素将被父级层叠上下文同化。

2. MDN文档分析

示例解释

因为div1-div5 祖先元素中只有html产生了层叠上下文,即div1-div5属于一个层叠上下文,符合以上规则。

div1-div4属于【6】:z-index为0或者auto的定位元素。div5属于【3】: 非定位 的块级元素。因此div5在div1-div4下面。

div1-div4同属于【4】,因此按照html中的顺序依次堆叠。

示例解释

同样,div1-div5都属于html这个层叠上下文。

div1,div5 属于【6】:z-index为0或者auto的定位元素。 div2,div3属于【4】:非定位 的 浮动 元素。 div4属于【3】:非定位 的块级元素。

因此顺序是:div4,div2,div3,div1,div5。

疑问:当给div4设置opacity非1之后(产生层叠上下文),顺序成了div2,div3,div1,div4,div5.像是理解为div4成了定位元素。因此在div1与div5之间,因为HTML中出现的顺序是div1,div4,div5。

示例解释

同样,div1-div5都属于html这个层叠上下文。

div1-div4同属于【7】:定位 的 z-index 大于 0 元素。 div5虽然有z-index但是对于该元素为非定位元素,所以无效,因此属于【3】:非定位 的块级元素。

在div-div4中,dom与z-index的关系:

div1: 5
div2: 3
div3: 2
div4: 1

因此最终顺序为:div5,div4,div3,div2,div1.

示例解释

div1-div6都形成了层叠上下文,属于【2】:相对,绝对定位元素,且z-index不为auto。

div1-div3 父层叠上下文为html,即祖先元素中唯有html为层叠上下文。 div4-div6 父层叠上下文为div3,即最近的层叠祖先元素为div3。

div1: 5
div2: 2
div3: 4
    div4: 6  理解为 4.6
    div5: 1  4.1  
    div6: 3  4.3

因此层叠顺序为: div2, div3, div5, div6, div4, div1

示例解释

div1-div4都是定位元素,div1是div2父元素,div3是div4父元素。

此时因为div1-div4都没有生成层叠上下文,同属于html层叠上下文中,所以层叠顺序为: div1,div2,div3,div4。

因为在同一堆叠上下文中,故此时给div2或者div4设置z-index时,即会使得div2或者div4在其它元素之上。

示例解释

div1-div4都是定位元素,div1是div2父元素,div3是div4父元素。

div1-div3同属于html层叠上下文,div4属于div3层叠上下文:

div1 : auto
div2 : 2
div3 : 1
    div4: 1.10

因此层叠顺序为: div1,div3,div4,div2

示例解释

dom结构:

level1
    container1
        level2
            container2
                level3
                level3
        level2
            container2
                level3
                level3
level1

一级菜单level1相对定位,但没有产生层叠上下文。

此时如果container1没有产生层叠上下文,则level2与level1同属html层叠上下文。此时根据HTML中出现的顺序,第一个level1下的level2会出现在第二个level1下面。

为使得所有level2出现在所有level1上面,则可以给level2设置z-index,(level2产生了层叠上下文)。同一层叠上下文下,z-index决定层级。

示例解释

<html>
<div class='div1'>
  <span class="red">Red</span>
</div>
<div class='div2'>
  <span class="green">Green</span>
</div>
<div class='div3'>
  <span class="blue">Blue</span>
</div>
</html>

.red, .green, .blue {
  position: absolute;
}

即 red,green,blue 都是绝对定位,且它们的父级div1-div3都没有形成层叠上下文,所以所有的元素同属于一个html的层叠上下文,因此给.red添加z-index会使得该元素显示在green和blue上面。

为了让red显示在green,blue下面,首先根据html出现顺序,div1层级在div2和div3下面,则只要保持层级不变,同时让div1变成层叠上下文,则.red的层级作用在div1上,即能让.red在div2,div3下面。

2.9 antd中的弹窗类组件

antd中一些弹出类的组件,假如结构:

<html>
    <div class='div1'>
        <Modal>
    </div>
    <div class='div2'>  // 疑问2,它必须是层叠上下文「opacity:0.99」时,123才会显示在modal上面. 为什么不是默认就在modal上面(按照HTML出现顺序排列)
        123
    </div>
</html>

即使你给modal很高的层级,可能仍然覆盖不了123: 比如这种情况:

div.div1 {
    opacity: 0.99;   //任何能使它成为层叠上下文,又不影响原有层级的属性(即不要设置定位元素与z-index)
}

此时div1的层级必然小于div2,则Modal的层级z-index再大也没效果,都不能覆盖123。此时的解决办法是让div1的层级大于div2的层级。比如:

div.div1 {
    position: relative;
    z-index:1;
}

但此时得确保div.div2的层级小于div1,即不能设置定位且z-index>=1. 否则123又会被覆盖。

基于以上的所有情况,最好的办法就是antd那样,将Modal的实际DOM作为body的直接子元素,加在body的最后。

注意:只有z-index会影响层叠顺序,opacity只是创造层叠上下文,不会改变层叠顺序,因此:

div.div1 {
    opacity: 0.99;   // 此时div1任然在div2下面,但是由于创造了层叠上下文,导致.red只是在div1中起效果
}

3. 参考资料及疑问

在2.2和2.9中分别有一处暂时不能解释的疑问

PreviousImmutable相关知识Next两列布局,三列布局

Last updated 4 years ago

Was this helpful?

2.1

2.2

2.3

2.4

2.5

2.6

2.7

2.8

Stacking without z-index
堆叠与浮动
Adding z-index
层叠上下文
Stacking context example 1
Stacking context example 2
Stacking context example 3
没人告诉你关于z-index的一些事
MDN:理解css的z-index属性
antd中弹窗类组件默认作为body子组件的参考
没人告诉你关于z-index的一些事
z-context chrome插件,分析元素的层叠上下文以及z-index