CSS深入理解之z-index
慕课学习-->前端开发-->HTML/CSS-->CSS深入理解之z-index
Z-index
一、Z-index基础
1、z-index属性指定了元素及其子元素的z顺序 ,而z顺序 可以决定当元素发生覆盖的时候,哪个元素在上面。通常一个较大z-index值的元素会覆盖较小z-index值的元素。
2、属性值:
(1)z-index:auto; 默认值
(2)z-index:<integer>; 整数值
(3)z-index:inherit; 继承
3、基本特性
(1)支持负值;
(2)支持CSS3 animation动画;
(3)在CSS 2.1时代,需要和定位元素配合使用。如果不考虑CSS3,只有定位元素(position:relative/absolute/fixed/sticky)的z-index才有作用!
二、z-index与CSS定位属性
1、重点:z-index只对定位元素有作用。position:relative/absolute/fixed/sticky;时z-index有效。
2、如果定位元素z-index没有发生嵌套:
(1)后来居上的准则;
(2)哪个大,那个上。
3、如果定位元素z-index发生嵌套:
(1)祖先优先原则,前提:祖先z-index值是数值,非auto!
后来者居上,第二个在上层
<body>
<div style="position:relative;z-index:1;">
<img src="1.png" style="position:absolute;z-index:2;">
</div>
<div style="position:relative;z-index:1;">
<img src="1.png" style="position:relative;left:100px;z-index:1;">
</div>
</body>
第一个祖先元素z-index:auto,第一个在上层。CSS2.1:(z-index:auto)当前层叠上下文的生成盒子层叠水平是0,盒子(除非是根元素)不会创建一个新的层叠上下文。
<body>
<div style="position:relative;z-index:auto;">
<img src="1.png" style="position:absolute;z-index:2;">
</div>
<div style="position:relative;z-index:1;">
<img src="1.png" style="position:relative;left:100px;z-index:1;">
</div>
</body>
三、CSS中层叠上下文和层叠水平
1、层叠上下文(stacking context)
层叠上下文(stacking context)是HTML元素中的一个三维概念,表示元素在z轴上有了“可以高人一等”。
页面根元素天生具有层叠上下文,称之为“根层叠上下文”。
设置z-index值为数值的定位元素也具有层叠上下文。
2、层叠水平(stacking level)
层叠上下文中的每个元素都有一个层叠水平,决定了同一个层叠上下文中元素在z轴上的显示顺序。遵循“后来居上”和“谁大谁在上层”的层叠准则。
层叠水平和z-index不是一个东西。普通元素也有层叠水平。
3、层叠上下文几个特性:
层叠上下文可以嵌套,组合成一个分层次的层叠上下文;
每个层叠上下文和兄弟元素独立:当进行层叠变化或渲染的时候,只需要考虑后代元素;
每个层叠上下文是自成体系的:当元素的内容被层叠后,整个元素被认为是在父层的层叠顺序中。
四、元素的层叠顺序
1、层叠顺序(stacking order)
层叠顺序(stacking order)是指元素发生层叠时有着特定的垂直显示顺序。
层叠顺序的意义:规范元素重叠时候的呈现规则。
为何层叠顺序是这样的?:更符合页面加载的功能和视觉呈现!一般来讲,background和border是装饰页面的,block和float是页面布局,而inline大部分是页面内容。内容是页面最重要的实体,因此层叠水平要高!
<style type="text/css">
.inline-block,.block{width:200px;height:100px;color:#fff;}
.inline-block{display:inline-block;background-color:olive;margin:-30px;}
.block{display:block;background-color:green;}
</style>
<body style="padding:50px;">
<div id="" class="inline-block">inline-block</div>
<div id="" class="block">block</div>
</body>
背景色覆盖是层叠顺序,文字覆盖是后来居上。如果元素的display水平一样且五特殊属性,发生层叠的时候,后面的覆盖前面的,所以文字覆盖。
五、z-index与层叠上下文
1、z-index的实际行为表现
(1)定位元素默认z-index:auto可以看成z-index:0;
(2)z-index不为auto的定位元素会创建层叠上下文;
(3)z-index层叠顺序的比较止步于父级层叠上下文;
2、为何定位元素会覆盖普通元素?
(1)若无定位,元素遵循后来者居上原则
<style type="text/css">
img{width:200px;}
</style>
<body>
<img src="1.png">
<img src="1.png" style="margin-left:-80px;">
</body>
(2)将第一个图片relative定位,则定位元素覆盖普通元素
<style type="text/css">
img{width:200px;}
</style>
<body>
<img src="1.png" style="position:relative;">
<img src="1.png" style="margin-left:-80px;">
</body>
此时第一个图片的z-index值是auto(定位元素未设置z-index是默认为auto),可以看成z-index:0,层叠顺序大于图片这个inline水平元素,所以会覆盖。
3、z-index与创建层叠上下文
(1)
<style type="text/css">
.box{position:absolute;background:blue;}
img{position:relative;width:200px;margin:50px 50px 50px -50px;}
</style>
<body style="margin:100px;">
<div id="" class="box">
<img src="1.png" style="">
</div>
</body>
(2)图片添加z-index:-1,背景覆盖图片。
<style type="text/css">
.box{position:absolute;background:blue;}
img{position:relative;width:200px;margin:50px 50px 50px -50px;z-index:-1;}
</style>
<body style="margin:100px;">
<div id="" class="box">
<img src="1.png" style="">
</div>
</body>
(3)给容器添加z-index:0,图片在上层。
<style type="text/css">
.box{position:absolute;background:blue;z-index:0;}
img{position:relative;width:200px;margin:50px 50px 50px -50px;z-index:-1;}
</style>
<body style="margin:100px;">
<div id="" class="box">
<img src="1.png" style="">
</div>
</body>
原因是z-index负值的层叠顺序在层叠上下文元素背景色之上。
第二步给图片设置z-index:-1时,容器绝对定位只是一个普通元素,不具有层叠上下文,所以图片的层叠上下文元素是页面根元素。但是,一旦容器z-index值为数值(第三步),图片的层叠上下文就变成了容器。定位元素的z-index不是auto的时候,就会创建层叠上下文。于是图片就在背景色上显示了。
从层叠顺序上讲,z-index:auto可以看成z-index:0。但从层叠上下文来讲,两者有着本质差异,auto不会创建层叠上下文,z-index:0会创建层叠上下文。(IE7下auto也会创建层叠上下文)
4、z-index受限于层叠上下文
<style type="text/css">
.box1{position:relative;z-index:0;}
.box1 img{position:absolute;z-index:9999;width:200px;}
.box2{position:relative;z-index:1;left:100px;}
.box2 img{position:absolute;z-index:-1;width:200px;}
</style>
<body>
<div class="box1">
<img src="1.png">
</div>
<div class="box2">
<img src="1.png">
</div>
</body>
虽然第一个图片的z-index值远远大于第二个图片,但他们的容器均为定位元素且z-index值为数值,会创建层叠上下文,第二个容器的z-index值更大,所以第二个图片覆盖了第一个图片。所以说z-index受限于层叠上下文。
六、其他CSS属性与层叠上下文
1、其他参与层叠上下文的属性们
(1)z-index值不为auto的flex项(父元素display:flex|inline-flex);
(2)元素的opacity值不是1;(元素透明度不是1)
(3)元素的transform值不是none;
(4)元素mix-blend-mode值不是normal;(混合模式)
(5)元素的filter值不是none;(滤镜为none)
(6)元素的isolation值是isolate;(元素是孤立的)
(7)position:fixed声明;(部分浏览器)
(8)will-change指定的属性值为上面任意一个;
(9)元素的-webkit-overflow-scrolling设为touch。(移动端)
图一 图二
因为box不是层叠上下文元素,图片在根元素(第一个层叠上下文元素)的上面,显示结果为图一。
2、display:flex与层叠上下文
<style type="text/css">
.box{background:blue;display:flex;}
.box>div{z-index:1;}
.box>div>img{position:relative;margin:50px 50px 50px -50px;z-index:-1;width:200px;}
</style>
<body style="padding-left:100px;">
<div class="box">
<div id="" class="">
<img src="1.png">
</div>
</div>
</body>
当我们给box设置display:flex时,box成为层叠上下文元素,显示结果为图二。Box成为层叠上下文元素并不是因为给box设置display:flex,而是因为子元素的z-index值不为auto。
3、透明度opacity不为1与层叠上下文
<style type="text/css">
.box{background:blue;opacity:0.5;}
.box>img{position:relative;margin:50px 50px 50px -50px;z-index:-1;width:200px;}
</style>
<body style="padding-left:100px;">
<div class="box">
<img src="1.png">
</div>
</body>
当我们给box设置opacity:0.5;时,box成为层叠上下文元素,显示结果为图二。
4、transform值不为none与层叠上下文
<style type="text/css">
.box{background:blue;transform:rotate(15deg);}
.box>img{position:relative;margin:50px 50px 50px -50px;z-index:-1;width:200px;}
</style>
<body style="padding-left:100px;">
<div class="box">
<img src="1.png">
</div>
</body>
为box设置transform:rotate(15deg);后,box成为层叠上下文元素,显示结果如图所示。
5、混合模式mix-blend-mode值不为normal与层叠上下文
<style type="text/css">
.box{background:blue;mix-blend-mode:screen;}
.box>img{position:relative;margin:50px 50px 50px -50px;z-index:-1;width:200px;}
</style>
<body style="padding-left:100px;">
<div class="box">
<img src="1.png">
</div>
</body>
为box设置mix-blend-mode:screen;后,box成为层叠上下文元素,图片显示在上层。
6、filter值不为none与层叠上下文(CSS3特有的滤镜)
<style type="text/css">
.box{background:blue;filter:blur(5px);}
.box>img{position:relative;margin:50px 50px 50px -50px;z-index:-1;width:200px;}
</style>
<body style="padding-left:100px;">
<div class="box">
<img src="1.png">
</div>
</body>
为box设置filter:blur(5px);模糊5像素后,box成为层叠上下文元素,图片显示在上层。效果如图所示。
7、isolation:isolate与层叠上下文
<style type="text/css">
.box{background:blue;isolation:isolate;}
.box>img{position:relative;margin:50px 50px 50px -50px;z-index:-1;width:200px;}
</style>
<body style="padding-left:100px;">
<div class="box">
<img src="1.png">
</div>
</body>
当我们给box设置isolation:isolate;时,box成为层叠上下文元素,显示结果为图二。
8、position:fixed与层叠上下文
<style type="text/css">
.box{background:blue;position:fixed;}
.box>img{position:relative;margin:50px 50px 50px -50px;z-index:-1;width:200px;}
</style>
<body style="padding-left:100px;">
<div class="box">
<img src="1.png">
</div>
</body>
当我们给box设置position:fixed;时,box成为层叠上下文元素,显示结果为图二。(只在Chrome等blink/webkit内核浏览器)(Firefox也可以)
9、will-change与层叠上下文
<style type="text/css">
.box{background:blue;will-change:transform;}
.box>img{position:relative;margin:50px 50px 50px -50px;z-index:-1;width:200px;}
</style>
<body style="padding-left:100px;">
<div class="box">
<img src="1.png">
</div>
</body>
当我们给box设置will-change:transform;时,box成为层叠上下文元素,显示结果为图二。
七、z-index与其他CSS属性层叠上下文
1、不支持z-index的层叠上下文元素的层叠顺序均是z-index:auto级别;
2、例子
图片1-5,依次为最底层到最上层。img1是inline水平元素;img2,img3,img4,img5为不依赖z-index的层叠上下文元素,同级别遵循后来者居上原则,img5覆盖umg4覆盖umg3覆盖umg2;
3、依赖z-index的层叠上下文元素的层叠顺序取决于z-index值
(1)依赖z-index值创建层叠上下文的情况:
a、position值为relative/absolute或者fixed(部分浏览器)
b、display:flex|inline-flex容器的子flex项
(2)例子
<style type="text/css">
.a{position:absolute;z-index:1;}
.box{background:blue;display:flex;margin-left:200px;}
.box>img{z-index:1;margin:50px 50px 50px -50px;}
</style>
<body style="padding-left:100px;">
<img src="1.png" class="a">
<div class="box">
<img src="1.png">
</div>
</body>
两个图片的z-index值都为1,同一个层叠水平,第二个图片覆盖第一个,遵循后来者居上原则。
若将flex图片的z-index值改为-1,display:flex元素是普通元素,他的子项是层叠上下文元素,寻找父级层叠上下文元素(也就是根元素),所以会被父级覆盖。
若将flex图片的z-index值改为0,层叠顺序在block水平之上。
4、层叠上下文导致的有趣的现象
<style type="text/css">
text{position:absolute;left:110px;top:110px;color:#FFF;}
img{
animation:fadein 5s 1;
-webkit-animation:fadein 5s 1; /* Safari 和 Chrome */
}
@keyframes fadein{
from{opacity:0;}
to{opacity:1;}
}
</style>
<body style="padding-left:100px;">
<text>图片说明,我是什么什么!</text>
<img src="1.png">
</body>
透明度为1(opacity:1)为普通元素,其他透明度值则新建层叠上下文,层叠顺序z-index:auto级别,跟absolute文字一样,但遵循后来居上原则,于是淡出的时候,文字是看不见的,知道东湖结束,此时opacity值为1,文字可见。
八、z-index实践
1、最小化影响原则
目的:是为了避免z-index嵌套层叠关系混乱;
造成混乱的原因:元素的层叠水平主要由所在的层叠上下文决定;IE7的z-index:auto也会新建层叠上下文。
做法:避免使用定位属性;定位属性从大容器评级分离为私有小容器。
2、不犯二准则
目的:避免z-index混乱,一山比一山高的样式问题。
原因:多人协作以及后期维护造成的;
做法:对于非浮层元素,避免设置z-index值,z-index值没有任何道理需要超过2-----不犯二准则。
3、组件层级计数器
目的:避免浮层组件因z-index被覆盖的问题
原因:总会遇到意想不到的高层及元素;组件的覆盖规则具有动态性。
做法:组件层级计数器方法(通过JS获取body下元素的最大z-index值)
4、可访问性隐藏
可访问性隐藏:人肉眼看不见,但是辅助设备可以识别。
设置z-index负值的元素,在层叠上下文的背景之上,其他元素之下。
下一篇: 深入理解position: fixed