今天写代码用antd-mobile的checkbox时候,想在内容文本后面添加一个icon,而且须要对这个icon绑定事件,发现绑定以后怎么也点不中,调试发现原来被层层嵌套的dom元素盖住了,确定是z-index在做祟。但是按照我以前对z-index的了解(自信满满)却怎么也不能把他由“被盖住”改为“盖住别人”,在一通“盲改”代码以后,终于“盖住”其余dom元素了。然而内心老是在想难道以前本身对z-index的认知有问题么,抱着这样的心态决定从新去学习,下面进入正文css
其实我想说大部分前端开发是不重视css的,也就致使了对css的不少属性认知都是表面的,这其中z-index就是最典型的一个,下面列举的错误认知还请你们对号入座:html
例以下面的例子:要比较div1-1-1 和 div2-1 是要看div1 和 div2 的比较结果呢前端
<div class="div1"> <div> <div class="div1-1-1" /> </div> </div> <div class="div2"> <div class="div2-1" /> </div>
若是以上三个你们都中枪了,不要紧,看完这篇文章你就永远告别了,在遇到z-index的问题不再会“盲改,乱试”了web
层叠顺序(stacking order)
层叠顺序表示发生层叠时有着特定的垂直显示顺序(规则)。
即:网上这张很流行的规则浏览器
关于这张图有一些补充:
位于最下面的background/border特指层叠上下文元素的边框和背景色。每个层叠顺序规则仅适用当前层叠上下文元素的小世界
inline水平盒子指的是包括inline/inline-block/inline-table元素的层叠顺序,他们都是同级别的
单纯从层叠水平上看,实际上z-index:0和auto是能够当作同样的,可是在层叠上下文领域有着根本性的差别antd
层叠上下文的层叠水平要比普通元素高
层叠上下文能够阻断元素的混合模式
层叠上下文能够嵌套,内部层叠上下文及其全部子元素均受制于外部的层叠上下文
每一个层叠上下文和兄弟元素独立,也就是说,当进行层叠变化或者渲染的时候,只须要考虑后代元素
每一个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中dom
根元素 (HTML)
z-index 值不为 "auto"的 绝对/相对定位(在firefox/ie浏览器下position: fixed也是能够的)
一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex
opacity 属性值小于 1 的元素(参考 the specification for opacity)
transform 属性值不为 "none"的元素
mix-blend-mode 属性值不为 "normal"的元素
filter值不为“none”的元素
perspective值不为“none”的元素
isolation 属性被设置为 "isolate"的元素
position: fixed
在 will-change 中指定了任意 CSS 属性,即使你没有直接指定这些属性的值(参考这篇文章)
-webkit-overflow-scrolling 属性被设置 "touch"的元素学习
层叠上下文与层叠顺序flex
文章中屡次提到普通元素具有层叠上下文后层叠水平就会变高,那么他究竟在层叠顺序那个规则图的哪一个位置呢
把目光向上锁定,第二条列举了12个能够建立层叠上下文的方法,咱们把他分为两类:第二三条和其余。
依赖z-index取值的:位置取决于z-index的值
不依赖z-index取值的:在图中第二高的位置,即:z-index = auto 或者 0spa
用一个例子来讲明:
<div class="container"> <div class="div1">111</div> <div class="div2">222</div> </div>
.container { width: 500px; height: 500px; background-color: #000; color: #fff; transform: scale(1); /* 给container建立层叠上下文 */ } .div1 { padding: 50px; background-color: aqua; z-index: 0; position: relative; /* 给div1建立层叠上下文,层叠水平依赖z-index的取值 */ } .div2 { padding: 50px; background-color: red; opacity: 0.8; /* 给div2建立层叠上下文,层叠水平依赖z-index的取值 */ /* margin-top: -40px; */ }
这个例子中一目了然,div1和div2的层叠水平同样,都是在规则那张图的第二高的位置,不过div2在div1的dom节点后面,因此div2要比div1的层叠水平高,咱们把margin-top的注释去掉看下:
要想使得div1在上面只须要把div1的z-index改为大于0的值就行了。
仍是上面的htl结构,接下来咱们再来看一个有意思的例子:
.container { width: 500px; height: 500px; background-color: #000; color: #fff; transform: scale(1); /* 给container建立层叠上下文 */ } .div1 { padding: 50px; background-color: aqua; opacity: 0.8; /* 给div1建立层叠上下文,层叠水平在z-index:0 */ } .div2 { padding: 50px; background-color: red; position: relative; margin-top: -40px; }
你们确定会说,div1明显盖过div2啊,但是咱们来看下实际状况:
实际状况下面的div2盖过了div1,缘由是当html元素设置定位属性的时候(absolute/relative),其z-index属性自动生效变成
z-index: auto,因此这时候div1和div2的层叠水平是一致的,而div2在div1的dom节点后面,因此盖过了div1(注意这里div2并无变成层叠上下文元素,这是有本质区别的)
如今咱们在一块儿看下文章开头提到的几个常见的错误认知:
文章到这里就结束了,但愿看完这篇文章的同窗能够完全理解z-index。