当前位置: 首页 > Web前端 > CSS

z-index与级联上下文

时间:2023-03-30 15:59:29 CSS

z-index基本介绍:在三维坐标空间中,通常用x轴表示水平位置,y轴表示垂直位置,z轴用于表示纸张内外的位置,如下图:css允许的z-index值有●auto(自动,默认值)●(整数)●inherit(继承)当设置为整数时,值越大,越接近用户。如果两个元素放在一起,占据一个公共区域,那么z-index高的元素会覆盖掉z-index低的元素的公共区域部分。关于z-index的三点思考●当一个定位元素有z-index值,和正常文档流中的元素重叠时,谁会被放在最上面?●当一个定位元素和一个浮动元素重叠时,谁被放在最上面?●z-index必须和定位一起使用才能生效吗?●z-index大的元素一定会覆盖z-index小的元素吗?解决上述问题需要深入理解z-index的原理,以及层叠上下文和层叠顺序。stackingcontext的概念:stackingcontext是HTML中的一个三维概念。相当于在水平面上创建了一个z轴,有层叠上下文的元素会离用户更近。它包含一组相互叠加的元素。我们创建的每一个网页都有一个默认的层叠上下文,层叠上下文的根是html,所有其他元素都会在这个层叠上下文中占据一个层级,或高或低。Stackingorder:Stackingorder:这是一个规则,表示当元素重叠时在z轴上的显示顺序。在一个堆叠上下文中,有七种堆叠顺序:(1)backgroundandborder:建立堆叠上下文的元素的背景和边框,栈中的最低层(2)negativez-index:当z-index为negative产生的级联上下文(3)block-levelbox:文档流中的普通块级元素(4)floatingbox:非定位浮动框(5)inlinebox:文档流中的inline-levelbox(6)z-index:0定位建立新层叠上下文的元素。(7)positivez-index:栈中的最高层。内联元素在页面中的堆叠顺序之所以高于浮动元素和块元素,是因为浮动和块级框主要用于布局,而内联元素用于显示页面内容。比他高那么多。ps:图片inline和inline-block中缺失的信息是同一层级z-index:0其实和z-index:auto是一样的,简单的从stacking层级上看。级联顺序规则谁大谁先:当同一个级联上下文字段中有明显的级联级别标记,比如z-index值时,级联级别值大的会覆盖小的:当元素级联当层级一致且堆叠顺序相同时,DOM流中后面的元素会覆盖前面的元素。层叠上下文元素的特点●层叠上下文的层叠层次高于普通元素;●层叠上下文可以嵌套,内层层叠上下文及其所有子元素都服从于外层层叠上下文。●每个层叠上下文不影响其兄弟元素,在进行层叠变化或渲染时,只与该元素的后代元素相关。●每个堆栈上下文都是独立的。当元素被堆叠时,它们的堆叠顺序取决于父堆叠上下文的堆叠顺序。级联上下文创建(1)根级联上下文:指的是页面的根元素,即html元素。这就是为什么当绝对定位元素定位到left/top等值时,如果没有其他定位元素的影响,就会相对于浏览器窗口定位。(2)定位元素包含position值为relative或absolute的定位元素,FireFox/IE浏览器(Chrome等webkit内核浏览器固定自动形成级联上下文,无需设置z-index为值)在position:fixed定位元素下,当其z-index值不为auto时,将创建一个堆叠上下文。演示:(1)

结果:(2)
结果:原因:z-index值为auto,为普通元素。两个img层不受parentlevel的影响。根据规则,以较大者为准因此,z-index为2的猫覆盖z-index为1的狗z-index:0将创建一个堆叠上下文。至此,级联规则发生了变化。堆叠上下文特征中的最后一条规则,每个堆叠上下文都是独立的。两个img的堆叠顺序比较,就变成了对其父级堆叠上下文元素的堆叠顺序的优先级比较。由于两者都是z-index:0,大小相同,此时按照级联规则从后面来,根据在DOM中出现的先后顺序来判断谁在最上面,所以后面的狗覆盖了猫。此时img元素上的z-index是没有意义的。E6/IE7浏览器有一个bug,就是用z-index:auto定位元素也会创建一个层叠上下文。(3)CSS3下的级联上下文CSS3的一些新属性会创建局部级联上下文,transform属性会改变绝对定位的word元素的包含块。以下几种情况会产生新的层叠上下文:1.z-index值不为auto的flexitem(父元素display:flex|inline-flex)。2.元素的不透明度值不是1.3。元素的转换值不是none.4。元素的mix-blend-mode值不正常。5、元素的过滤值不是none。6.元素的隔离值为isolate。7、will-change指定的属性值为以上任意一种。8、元素的-webkit-overflow-scrolling设置为touch.display:flex|inline-flexstackingcontext需要满足两个条件才能形成stackingcontext:(1)parent需要是display:flex/inline-flex(2)子元素的z-index不是auto,必须是一个值。此时这个子元素是一个堆叠上下文元素,是的,注意,是子元素,不是flex父元素demo:
.boxdiv{width:300px;高度:300px;背景色:粉色;z-index:101;}.boxdivimg{宽度:400px;200像素;位置:相对;z-index:-1;}结果:原因:此时的div是一个普通元素,其上设置的z-index无效,img的负值z-index会被块级元素屏蔽为阻止。Continuation:.box{display:flex;}结果:给div加上flex值后,此时z-index会生效,使其子元素和内部div形成一个层叠上下文。根据7层的堆叠顺序,背景层将被负z-index层遮挡。flex的出现打破了z-index必须配合定位元素才能生效的传统观念。不透明度和堆叠上下文
div{width:300px;高度:300px;背景色:粉色;}divimg{宽度:400px;高度:200px;位置:相对;z-index:-1;}结果:给div添加一个不透明度属性:div{width:300px;高度:300px;背景色:粉色;不透明度:0.5;/*添加opcity属性*/}只要设置的opacity值不为1,就会形成级联上下文。性能结果:transform对stackingcontext的影响同上。在最外层的div上设置transform:rotate(15deg)会形成层叠上下文,导致图片显示在div之上。transform除了建立局部的堆叠上下文外,还会改变绝对定位的子元素的containingblock(固定定位也是绝对定位的一种)。containingblock的概念:一些盒子根据它外面的矩形盒子来计算自己的定位和大小。外部矩形框是包含块。对固定定位元素的影响:普通的固定定位包含块是viewport,加入transform就不一样了div{宽度:100px;高度:100px;}#fixed{位置:固定;宽度:100%;高度:100%;顶部:0;左:0;背景:蓝色;}#transform{背景:红色;20px;}fixed将填满整个屏幕。结果:添加#transform{transform:scale(1);}结果:原因是固定的包含块不再是viewport,而是transformdiv的边缘。所以fixed的宽高都是140px,对绝对定位元素的影响:#relative{位置:相对;宽度:100px;高度:100px;背景:绿色;}#absolute{位置:绝对;宽度:100%;高度:100%;顶部:0;左:0;背景:蓝色;}#transform{背景:红色;宽度:50px;height:50px;}此时绝对包含块是相对内边距框的边缘框。所以absolute的宽高都是100px。将transform属性添加到transformdiv。结果:因为transform创建了一个局部堆叠上下文,所以absolute的包含块不再是relative而是transform。根据这个新的包含块,得到一个新的宽高。是50px。只要有transform属性,不管它的值是多少,都会影响到绝对定位的子包含块。总结:stackingcontext的元素的堆叠顺序是哪一层:依赖z-index值的元素根据z-index的值来确定。对于不依赖于z-index值的元素,其z-indexauto值相当于z-index:0级别。第二种情况解释了为什么定位元素会覆盖普通流元素。默认情况下,定位元素将添加z-index:auto。按照7个堆叠顺序,普通流的元素会被覆盖。当z-index的值为auto时,也就是说当stackingcontext的元素和定位元素的堆叠顺序相同时,重叠时,后面的元素会覆盖上面的元素:上面元素交换位置:z-index本质上就是谁大谁在上面。虽然css3新增的一些属性让z-index更加复杂,最常见的影响可能是flex布局造成的,但是规则还是按照7个堆叠顺序排列。