本人已参与新人「创作礼活动」,一起开启掘金创作之路。
一、关于z-index的四个思考
● 当一个设置了z-index值的定位元素与正常的文档流中的元素相互重叠的时候,谁会被置于上方?
● 当定位元素与浮动元素相互重叠的时候,谁会被置于上方?
● z-index必须要与定位一起使用才会生效吗?
● z-index大的元素一定会遮挡z-index小的元素吗?
二、z-index的原理
解决上面的问题需要深入理解z-index的原理,需要知道层叠上下文和层叠顺序
1、概念:
层叠上下文就是html中的一个三维概念。相当于在水平面创建了一个z轴,它包含了一组层叠层的元素。我们所创建的每一个网页都有一个默认的层叠上下文,层叠上下文的根就是html,其他的所有元素都会在这个层叠上下文占据一个层叠水平,或高或低。
2、层叠规则与顺序:
● 谁大谁上:在同一个层叠上下文中,层叠水平值大的那一个覆盖层叠水平值小的
● 后来居上:当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素
● 最近祖先比较:在不同层叠上下文中,要先找到其各自最近的且处于同层级的祖先,然后采用上面两种方法进行祖先层级水平比较,祖先层级水平高的覆盖祖先层级水平低的;取决于祖先层级水平,不取决于自身
在一个层叠上下文中,有七种层叠顺序:
提示: 页面中内联元素的层叠顺序要比浮动元素和块状元素都高,是因为浮动和块级盒子用来布局,而内联元素用来显示内容;所以比其他两者要高。
三、触发新的层叠上下文
- 根元素
<html></html>,默认的层叠上下文 - position值为 absolute|relative,且 z-index值不为 auto
- position 值为 fixed|sticky
- z-index 值不为 auto 的flex子元素,且父元素 display:flex|inline-flex;此时,该子元素为层叠上下文元素
- opacity 属性值小于 1 的元素
- transform 属性值不为 none 的元素
- will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值
- -webkit-overflow-scrolling 属性被设置 touch的元素
- mix-blend-mode 属性值不为 normal 的元素
- 元素的filter、 perspective、 clip-path、 mask、 mask-image、 mask-border、 motion-path 值不为 none 的元素
- isolation 属性被设置为 isolate 的元素
四、示例代码
- 示例一:层叠顺序代码验证(遮挡或部分文字重叠遮挡)
.box { width: 560px; height: 110px; background-color: rgba(255,255,2, 0.9); border: 20px solid red; }
.box .node1 { position: relative; z-index: -1; white-space: nowrap;}
.box .node1 .test1 { position: absolute; z-index: 9999; left: 50px; top: 20px; }
.box .node2 {}
.box .node3 { float: left; color: seagreen; white-space: nowrap; }
.box .node4 { color: blue; }
.box .node5 { position: relative; z-index: 0; color: rgb(255, 0, 234); top: -21px; left: 296px;}
.box .node6 { position: relative; z-index: 9; color: red; top: -42px; left: 112px;}
<div class="box">
<span class="node1">
负的z-index:z-index 为负值时形成的层叠上下文;负的z-index:z-index 为负值时形成的层叠上下文
<span class="test1">验证:形成新的层叠上下文,定位出去会被遮挡;验证:形成新的层叠上下文,定位出去会被遮挡</span>
</span>
<div class="node2">块级盒子: 文档流中正常的块级元素;</div>
<div class="node3">浮动盒子:非定位的浮动盒子;浮动盒子:非定位的浮动盒子;浮动盒子:非定位的浮动盒子;</div>
<span class="node4">行内盒:文档流内的行内级盒子; 行内盒:文档流内的行内级盒子</span>
<div class="node5">文档流内的行XXXX;z-index:0 定位元素,这些元素建立了新的层上下文。</div>
<div class="node6">正的z-index,级别最高,文档</div>
</div>
- 示例二:relative或absolute定位 + z-index 非auto触发新的层叠上下文
/* .box1 { position: relative; z-index: auto; } */
.box1 { position: relative; z-index: 1; }
.box1 img { position: absolute; z-index: 2; width: 300px; height: 200px; }
/* .box2 { position: relative; z-index: auto; } */
.box2 { position: relative; z-index: 1; }
.box2 img { position: absolute; z-index: 1; width: 200px; height: 300px; }
<div class="box1">
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F4k%2Fs%2F02%2F2109242332225H9-0-lp.jpg" alt="">
</div>
<div class="box2">
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2Ftp05%2F1910021010125G2-0-lp.jpg" alt="">
</div>
- 示例三:fixed、sticky定位触发新的层叠上下文
.box {}
/* .inner { width: 200px; height: 220px; background-color: pink; } */
.inner { position: fixed; width: 200px; height: 220px; background-color: pink; }
img { position: fixed; z-index: -1; width: 300px; height: 180px; }
<div class="box">
<div class="inner">
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F4k%2Fs%2F02%2F2109242332225H9-0-lp.jpg" alt="">
</div>
</div>
- 示例四:父元素flex + 子元素z-index 非auto触发新的层叠上下文
/* .box { display: flex; } */
.box { display: flex; }
.inner { width: 200px; height: 220px; z-index: 9; background-color: pink; }
img { position: relative; z-index: -1; width: 300px; height: 180px; }
<div class="box">
<div class="inner">
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F4k%2Fs%2F02%2F2109242332225H9-0-lp.jpg" alt="">
</div>
</div>
- 示例五:opacity < 1 触发新的层叠上下文
.box {}
/* .inner { width: 200px; height: 220px; background-color: pink; } */
.inner { opacity: 0.6; width: 200px; height: 220px; background-color: pink; }
img { position: relative; z-index: -1; width: 300px; height: 180px; }
<div class="box">
<div class="inner">
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F4k%2Fs%2F02%2F2109242332225H9-0-lp.jpg" alt="">
</div>
</div>
- 示例六:transform 非 none 触发新的层叠上下文
.box {}
.inner { transform: translateX(50px); width: 200px; height: 220px; background-color: pink; }
img { position: relative; z-index: -1; width: 300px; height: 180px; }
<div class="box">
<div class="inner">
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F4k%2Fs%2F02%2F2109242332225H9-0-lp.jpg" alt="">
</div>
</div>