一、什么是层叠上下文和层叠水平

层叠上下文和层叠水平有一点儿抽象。我们可以吧层叠上下问想象成一张桌子,如果有另一个桌子在他旁边,则代表了另一个层叠上下文。

Stacking context 1由文件根元素构建,Stacking context 2和Stacking context 3是在Stacking context 1的层叠水平之上,并且也创建的自己的层叠上下文,里面有一个新的层叠水平。

我们所创建的每个网页都有一个默认的层叠上下文,层叠上下文的根(上面假设的桌子)就是HTML元素,所有其他元素都会在这个默认的层叠上下文上占据一个层叠水平,或高或低。

二、层叠顺序

  • 背景和边框:建立层叠上下文元素的背景和边框。层叠中的最低级

  • 负 Z-index:z-index 为负的后代元素建立的层叠上下文

  • 块级盒:文档流内非行内级非定位后代元素

  • 浮动盒:非定位浮动元素(即排除了position:absolute/relative/fixed的浮动盒)

  • 行内盒:文档流内行内级非定位后代元素

  • Z-index: 0:定位元素。这些元素建立了新层叠上下文(笔者注:不一定,详见后文)

  • 正 Z-index:(z-index 为正的)定位元素。层叠的最高等级

注:

  1. 原图没有呈现inline-block的层叠顺序,实际上,inline-block和inline水平元素是同等level级别。
  2. z-index:0实际上和z-index:auto单纯从层叠水平上看,是可以看成是一样的。注意这里的措辞——“单纯从层叠水平上看”,实际上,两者在层叠上下文领域有着根本性的差异。

三、务必牢记的层叠准则

  1. 谁大谁上:当具有明显的层叠水平标示的时候,如识别的z-indx值,在同一个层叠上下文领域,层叠水平值大的那一个覆盖小的那一个。通俗讲就是官大的压死官小的。
  2. 后来居上:当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。

四、层叠上下文的创建

1.根层叠上下文
指的是页面根元素,也就是滚动条的默认的始作俑者<html>元素。这就是为什么,绝对定位元素在left/top等值定位的时候,如果没有其他定位元素限制,会相对浏览器窗口定位的原因。

2.定位元素与传统层叠上下文
对于包含有position:relative/position:absolute的定位元素,以及FireFox/IE浏览器(不包括Chrome等webkit内核浏览器)(目前,也就是2016年初是这样)下含有position:fixed声明的定位元素,当其z-index值不是auto的时候,会创建层叠上下文。

3.CSS3与新时代的层叠上下文

以下情况会产生新的层叠上下文:

  • 根元素(HTML)

  • 绝对或相对定位且 z-index 值不为 auto

  • 一个伸缩项目 Flex Item,且 z-index 值不为 auto,即父元素 display: flex|inline-flex

  • 元素的 opacity 属性值小于 1

  • 元素的 transform 属性值不为 none

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

  • 元素的 filter 属性值不为 normal

  • 元素的 isolation 属性值为 isolate

  • position: fixed

  • will-change 中指定了上述任意属性,即便你没有直接定义这些属性

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

1. display:flex|inline-flex与层叠上下文
注意,这里的规则有些负责复杂。要满足两个条件才能形成层叠上下文:条件1是父级需要是display:flex或者display:inline-flex水平,条件2是子元素的z-index不是auto,必须是数值。此时,这个子元素为层叠上下文元素,没错,注意了,是子元素,不是flex父级元素。

眼见为实,给大家上例子吧。

如下HTML和CSS代码:

<div class="box">
<div>
<img src="mm1.jpg">
</div>
</div>
.box {  }
.box > div { background-color: blue; z-index: 1; } /* 此时该div是普通元素,z-index无效 */
.box > div > img {
position: relative; z-index: -1; right: -150px; /* 注意这里是负值z-index */
}

结果如下:

会发现,妹子跑到蓝色背景的下面了。为什么呢?层叠顺序图可以找到答案,如下:

从上图可以看出负值z-index的层叠顺序在block水平元素的下面,而蓝色背景div元素是个普通元素,因此,妹子直接穿越过去,在蓝色背景后面的显示了。

现在,我们CSS微调下,增加display:flex, 如下:

.box { display: flex; }
.box > div { background-color: blue; z-index: 1; } /* 此时该div是层叠上下文元素,同时z-index生效 */
.box > div > img {
position: relative; z-index: -1; right: -150px; /* 注意这里是负值z-index */
}

结果:

会发现,妹子在蓝色背景上面显示了,为什么呢?层叠顺序图可以找到答案,如下:

从上图可以看出负值z-index的层叠顺序在当前第一个父层叠上下文元素的上面,而此时,那个z-index值为1的蓝色背景<div>的父元素的display值是flex,一下子升官发财变成层叠上下文元素了,于是,图片在蓝色背景上面显示了。这个现象也证实了层叠上下文元素是flex子元素,而不是flex容器元素。

另外,另外,这个例子也颠覆了我们传统的对z-index的理解。在CSS2.1时代,z-index属性必须和定位元素一起使用才有作用,但是,在CSS3的世界里,非定位元素也能和z-index愉快地搞基。

2. opacity与层叠上下文
我们直接看代码,原理和上面例子一样,就不解释了。

如下HTML和CSS代码:

<div class="box">
<img src="mm1.jpg">
</div>
.box { background-color: blue;  }
.box > img {
position: relative; z-index: -1; right: -150px;
}

结果如下:

然后价格透明度,例如50%透明:

.box { background-color: blue; opacity: 0.5;  }
.box > img {
position: relative; z-index: -1; right: -150px;
}

结果如下:

原因就是半透明元素具有层叠上下文,妹子图片的z-index:-1无法穿透,于是,在蓝色背景上面乖乖显示了。

3. transform与层叠上下文
应用了transform变换的元素同样具有菜单上下文。

我们直接看应用后的结果,如下CSS代码:

.box { background-color: blue; transform: rotate(15deg);  }
.box > img {
position: relative; z-index: -1; right: -150px;
}

结果如下:

妹子同样在蓝色背景之上。

4. mix-blend-mode与层叠上下文
mix-blend-mode类似于PS中的混合模式,之前专门有文章介绍-“CSS3混合模式mix-blend-mode简介”。

元素和白色背景混合。无论哪种模式,要么全白,要么没有任何变化。为了让大家有直观感受,因此,下面例子我特意加了个原创平铺背景:

.box { background-color: blue; mix-blend-mode: darken;  }
.box > img {
position: relative; z-index: -1; right: -150px;
}

结果如下:

需要注意的是,目前,IE浏览器(包括IE14)还不支持mix-blend-mode,因此,要想看到妹子在背景色之上,请使用Chrome或FireFox。

同样的,因为蓝色背景元素升级成了层叠上下文,因此,z-index:-1无法穿透,在蓝色背景上显示了。

5. filter与层叠上下文
此处说的filter是CSS3中规范的滤镜,不是旧IE时代私有的那些,虽然目的类似。同样的,我之前有提过,例如图片的灰度或者图片的毛玻璃效果等。

我们使用常见的模糊效果示意下:

.box { background-color: blue; filter: blur(5px);  }
.box > img {
position: relative; z-index: -1; right: -150px;
}

结果如下:

好吧,果然被你猜对了,妹子蓝色床上躺着,只是你眼镜摘了,看得有些不够真切罢了。

6. isolation:isolate与层叠上下文
isolation:isolate这个声明是mix-blend-mode应运而生的。默认情况下,mix-blend-mode会混合z轴所有层叠在下面的元素,要是我们不希望某个层叠的元素参与混合怎么办呢?就是使用isolation:isolate。由于一言难尽,我特意为此写了篇文章:“理解CSS3 isolation: isolate的表现和作用”,解释了其阻隔混合模式的原理,建议大家看下。

要演示这个效果,我需要重新设计下,如下HTML结构:

<img src="img/mm2.jpg" class="mode">
<div class="box">
<img src="mm1.jpg">
</div>

CSS主要代码如下:

.mode {
/* 竖妹子绝对定位,同时混合模式 */
position: absolute; mix-blend-mode: darken;
}
.box {
background: blue;
}
.box > img {
position: relative; z-index: -1;
}

结构如下:

会发现,横妹子被混合模式了。此时,我们给妹子所在容器增加isolation:isolate,如下CSS所示:

.mode {
/* 竖妹子绝对定位,同时混合模式 */
position: absolute; mix-blend-mode: darken;
}
.box {
background: blue; isolation:isolate;
}
.box > img {
position: relative; z-index: -1;
}

结果为:

会发现横着的妹子跑到蓝色背景上面了。这表明确实创建了层叠上下文。

7. will-change与层叠上下文
关于will-change,如果有同学还不了解,可以参见我之前写的文章:“使用CSS3 will-change提高页面滚动、动画等渲染性能”。

都是类似的演示代码:

.box { background-color: blue; will-change: transform;  }
.box > img {
position: relative; z-index: -1; right: -150px;
}

结果如下:

果然不出所料,妹子上了蓝色的背景。

五、层叠上下文与层叠顺序

一旦普通元素具有了层叠上下文,其层叠顺序就会变高。那它的层叠顺序究竟在哪个位置呢?

这里需要分两种情况讨论:

  1. 如果层叠上下文元素不依赖z-index数值,则其层叠顺序是z-index:auto可看成z:index:0级别;
  2. 如果层叠上下文元素依赖z-index数值,则其层叠顺序由z-index值决定。

六、总结

大多数情况下,z-index是不必要使用的。比如,知道了内联元素的层叠水平比块状元素高,于是,某条线你想覆盖上去的时候,只需要inline-block化就可以。

参考资料:http://webdesign.tutsplus.com/articles/what-you-may-not-know-about-the-z-index-property--webdesign-16892

    http://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/

CSS中的层叠上下文和层叠顺序的更多相关文章

  1. 深入理解CSS中的层叠上下文和层叠顺序(转)

    by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=5115 零.世间的道 ...

  2. 深入理解CSS中的层叠上下文和层叠顺序

    零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在C ...

  3. [转]深入理解CSS中的层叠上下文和层叠顺序

    http://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/ 零.世间的道理都是 ...

  4. 关于css的层叠上下文和层叠顺序问题

    关于css的层叠上下文和层叠样式问题 最近在项目中遇到了一个让我欲仙欲死的问题,我给项目中的图片设置了一个淡入效果,几opacity变化,但当我在它的上面有一个定位元素时,动画结束后,定位元素居然被遮 ...

  5. css 层叠上下文和层叠顺序

    层叠上下文是css中的一个三维概念,拥有层叠上下文的元素在z轴上比普通元素要高,而且其内部的所有内容是自成体系的,其后代都是在它的层叠顺序中 哪些元素拥有层叠上下文 1.根元素,也就是html默认拥有 ...

  6. CSS中继承,特殊性,层叠与重要性

    继承 CSS的某些样式是具有继承性的,那么什么是继承呢?继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代.比如下面代码: <html><head> ...

  7. css层叠上下文和层叠顺序

    普通元素的层叠水平优先由层叠上下文决定,因此,层叠水平的比较只有在当前层叠上下文元素中才有意义. 诸位千万不要把层叠水平和CSS的z-index属性混为一谈.没错,某些情况下z-index确实可以影响 ...

  8. css之层叠上下文和层叠顺序

    大家在写网页的时候会不会经常遇到莫名奇妙的样式问题,比如谁覆盖了谁.也找不出原因,为什么z-index高的却没有覆盖掉z-index低的元素呢? 带着这些疑问.我做了个小实验.代码如下: <st ...

  9. css中z-index属性(标签层叠次序)

    定义和用法 z-index 属性设置元素的堆叠顺序.拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面. 注释:元素可拥有负的 z-index 属性值. 注释:Z-index 仅能在定位元素上奏 ...

随机推荐

  1. 20155212 2016-2017-2 《Java程序设计》第7周学习总结

    20155212 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 Chapter13 取得系统时间的方法之一是System.currentTimeMillis ...

  2. MemCahced 使用及常见问题说明

    前言 本文档是针对Memcached使用及常见问题的说明. 一.获取 1. MemCached 官网:http://www.memcached.org 下载:http://memcached.org/ ...

  3. 可视化iOS应用程序开发的6个Xcode小技巧

    FIXME 该标签用来提醒你代码中存在稍后某个时间需要修改的部分.(编辑注:网络上有一些可以用来收集项目中`TODO`和`FIXME`标签的辅助插件,比如XToDo https://github.co ...

  4. 切勿用普通for循环遍历LinkedList

    ArrayList与LinkedList的普通for循环遍历 对于大部分Java程序员朋友们来说,可能平时使用得最多的List就是ArrayList,对于ArrayList的遍历,一般用如下写法: p ...

  5. [jquery-delegate] iphone_4s _iphone _5c_中不兼容jQuery delegate 事件(does not wok)

    1. jQuery .on() and .delegate() doesn't work on iPad http://stackoverflow.com/questions/10165141/jqu ...

  6. fastreport字体加粗

    procedure MasterData1OnBeforePrint(Sender: TfrxComponent); begin IF (<frxDB_cdsresult."res_C ...

  7. RequestHelper

    Request["param"] 全部 Request.QueryString["param"] get Request.Form["param&qu ...

  8. json--pyton中obj与json的互转,js中obj与json的互转

    json 解释:json是一种跨平台的通用的数据格式 python中对象(obj)与json之间的相互转换 1.对象(obj)转json格式的字符串 json.dumps(res) res = () ...

  9. wpf(使用定时器)使用定时器操作UI界面

    在项目实践中,我们 可能会遇到需要将一些控件上显示的内容只显示一段时间过后清空. 下面我们来实现这种操作: 首先需要注意的是:在wpf中涉及到界面操作的话,一定要使用定时器DispatcherTime ...

  10. Oracle数据库设置Scott登录

    Oracle数据库Scott登录 在安装数据库时,用户登录选项中,Scott用户默认是未解锁的. 用户名填写as sysdba:密码是原来设置的,登录进去,新建SQL窗口,输入命令: alert us ...