层叠上下文小结
前言
层叠上下文在我们开发中经常用到,但是自己在最新的工作中感觉认识的还不到位,所以这次想写一篇文章总结一下,加强自己的印象
什么是层叠上下文
我理解的层叠上下文就是,元素在z轴上有自己的一套层叠规则,和块级上下文是一个概念。那我们我们需要理解的是,层叠上下文如何产生以及层叠上下文的特点。
如何产生
- opacity 不为1(试了一下大于1的话也相当于没创建,只有小于1才会有效果)
- tansform和filter 不为none
- 元素isolation是isolate
- 元素的-webkit-overflow-scrolling设为touch.
- 元素mix-blend-mode值不是normal.
- 元素的isolation值是isolate.
- will-change指定的属性值为上面任意一个。
层叠上下文的特点是什么
- 层叠上下文一旦创建,会比普通的元素的层叠高,也就是会覆盖他们
- 层叠上下文中z-index谁大谁在上,在css2中只针对定位元素创造出来的层叠上下文, 因为z-index只针对定位元素有效果,在css3中display:flex || inline-flex并且子元素的z-index不为auto时候,也有效果
- 层叠上下文比较主要看最外层父元素的z-index大小,父元素的z-index一致,才去比较子元素,父元素的z-index比较小的话,就算子元素的z-index在大也没用
元素层叠比较
image.png上面引用的是张鑫旭深入理解CSS中的层叠上下文和层叠顺序,中的一张图,这篇文章的主要内容就是从这篇文章总结的,有兴趣可以点击进去看看。
说明1
浮动元素比block元素的层叠高,但是inline-block,inline比float元素的层叠高,因为文档中文字最重要,所以他们层叠比float高。
.test1 {
background-color: green;
height: 200px;
}
.test1-demo {
width: 200px;
height: 300px;
background-color: pink;
float: left;
}
.test2 {
background-color: blue;
height: 200px;
margin-top: -20px;
}
<div class="test1">
<div class="test1-demo"></div>
<span>我是hi你好久哦啊啊按a</span>
</div>
<div class="test2">我是第三个</div>
image.png
从上面可以看到test2的层叠是比test1要大的,因为后来者居上,但是由于test1里面的test-demo设置了float,从上图可以知道,他的层叠大于block
说明2
一旦设置了层叠上下文的话,在没有z-index的情况下,他的层叠比float,inline-block都高的
.test1 {
background-color: green;
height: 200px;
}
.test1-demo {
width: 200px;
height: 300px;
background-color: pink;
float: left;
display: inline-block;
z-index: 20;
}
.test2 {
background-color: blue;
height: 200px;
margin-top: -20px;
opacity: 0.99;
z-index: 2;
}
<div class="test1">
<div class="test1-demo"></div>
<span>我是hi你好久哦啊啊按a</span>
</div>
<div class="test2">我是第三个</div>
image.png
我们看到test2设置了opacity: 0.99 成了层叠上下文,所以就算test2-demo设置了float,也会覆盖他,还有就是虽然test1-demo设置z-index:20, test2设置z-index:2,但是因为他们不是定位元素,所以z-index没有效果。
说明3
.test1 {
background-color: green;
height: 200px;
position: relative;
z-index: 2;
}
.test1-demo {
width: 200px;
height: 300px;
background-color: pink;
position: relative;
z-index: 30;
}
.test2 {
background-color: blue;
height: 200px;
margin-top: -20px;
position: relative;
z-index: 20;
}
<div class="test1">
<div class="test1-demo"></div>
<span>我是第一个</span>
</div>
<div class="test2">我是第二个</div>
image.png
虽然test1-demo的z-index是30,比test1z-index:20要大,但是test1-demo的父元素test1的z-index是2,所以父元素比较是test2大,所以test1-demo在怎么大也不会覆盖下面的test2
说明4
如何父元素设置z-index:auto的时候,子元素不受父元素的影响
.test1 {
background-color: green;
height: 200px;
position: relative;
z-index: auto;
}
.test1 img {
position: relative;
z-index: 2;
}
.test2 {
background-color: blue;
height: 200px;
position: absolute;
z-index: auto;
top: 0;
}
.test2 img {
position: absolute;
z-index: 1;
}
<div class='test1'>
<img src="http://image.zhangxinxu.com/image/study/s/s256/mm1.jpg" />
</div>
<div class="test2">
<img src="http://image.zhangxinxu.com/image/study/s/s256/mm2.jpg" />
</div>
image.png
因为test1,test2都设置了z-index:auto所以子元素比较的时候,不考虑他们,因为test2 img 的z-index是1, test1 img的z-index是2所以宽的图片在长的图片上面
说明5
z-index本身是在定位元素有作用,但是在css3中的display:flex || inline-flex并且z-index不为auto也有效果
.box {
}
.test {
background-color: blue;
z-index: 1;
} /* 此时该div是普通元素,z-index无效 */
.test > img {
position: relative;
z-index: -1;
right: -150px; /* 注意这里是负值z-index */
}
<div class='box'>
<div class='test'>
<img src="http://image.zhangxinxu.com/image/study/s/s256/mm1.jpg">
</div>
</div>
</div>
image.png
我们发现图片在下面,因为虽然设置了test 的z-index:1,但他既不是定位元素,也没有display: flex|| inline-flex所以z-index没有效果,又img设置了z-index为负,根据z-index为负数时候层叠样式在block下,把css改成如下
.box {
display: flex;
}
.test {
background-color: blue;
z-index: 1;
} /* 此时该div是普通元素,z-index无效 */
.test > img {
position: relative;
z-index: -1;
right: -150px; /* 注意这里是负值z-index */
}
image.png
一旦.box为display:flex,并且test的z-index不为auto,那么他就是一个层叠上下文,层叠上下文中的子元素设置z-index不会穿透,同样你也可以设置opacity,transform等让test变成层叠上下文,达到一样的效果,但是这里注意的是,虽然opacity和taransform等让test变成了层叠上下文,但是z-index依然没效果,只有display:flex,子元素z-index不为auto才有效果。
总结
以上实例可以总结出一下几点
- 如果没有层叠上下文,遵循后来居上原则
- 层叠上下文的层叠比普通的高(float,inline-block)
- 层叠上下文中只有定位导致层叠和父元素为display:flex并且子元素是z-index不为auto时候,z-index才有效果
- 层叠比较看父元素,父元素的z-index小,他的子元素的z-index在大也没有用
- 父元素的z-index有效的时候,子元素的z-index为负没有效果,无法穿透