- 1 . 什么是堆叠顺序?
- 2 . 什么是堆叠上下文?
堆叠顺序:
- background
- border
- 块级
- 浮动
- 内联
- z-index: 0
- z-index: +
判断一个人是否了解堆叠上下文的概念时,我想到了下面的这道题
看上面的图思考下面的这个问题:
border和background之间的关系是什么?
A:在同一面上,相平齐
B:border更加靠近用户
C:background更加靠近用户
为了验证上面的猜想,我引入0.5透明度border的现象来实现最终效果
显然可以看出:border更加靠近用户。
由此我们可以想到DIV它并不是一个平面的物体,也是有层次的概念。
通过平面和侧面的图也可以看出效果
同样,为了验证在DIV中写入文字验证最终效果:
侧面实际呈现是:
接着我在div的子元素引入的child来验证堆叠效果:
最终的结果是div的元素效果是盖不住文字(内联元素)效果。也就是说内联元素离用户更加接近。
最后我想到了一个同级化的问题,当我的子代出现内联元素和父级同时出现内联元素时,谁会更加接近用户的眼睛?
结果是非常明显的,谁最后写入谁就更加接近用户的眼睛(盖住前面元素)。
上面我们通过猜想验证的方式简单的介绍了border,background和块级元素,接下来我们再来验证一下浮动元素:
为了更直观的看出效果,我给内联元素‘你好’设置了text-indent: -10px;
效果如图:
很显然,内联元素的更加出现在上层,而浮动的元素天生优先于块级元素
截止至目前我们看到的所有效果:内联元素>浮动元素/浮动内联元素>块级元素>border>background
其中,有关于内联元素谁最后写入谁更加浮现在用户面前。
接下来我们接着比较绝对定位和相对定位元素的堆叠上下文的优先级谁更高?
可以看出经过绝对定位的元素优先级是高于浮动定位的元素的!
接下来比较z-index和position:relative之间的优先级:
通过对relative设置margin-top来清楚的可以看到relative的优先级是高于z-index的。
这时候我们得出一个结论:只有被定位的元素的优先级等级才会高于没有被定位的优先级的元素(position:static)
同样,通过上图我们可以得出,设置了relative的元素后出现的元素优先级一定高于先出现的元素。
而对relative设置了z-index(>=1)元素的优先级则高于没有设置z-index的relative的元素。
在考虑position:absolute与relative做对比时,同样也是只考虑z-index的影响:
上图说明对relative与absolute做比较时,谁后出现谁的优先级就更高。可以把absolute和relative当作同级来看待,但是如果对其中一个元素设置了z-index就会可以看出通过设置absolute/relative的元素优先级都会高于没有设置z-index的元素。
注:如果父元素z-index:0 子元素设置z-index:-1则子元素则会显示出来
所以说,正如自然界很多物质一样。我们无法解释它的原理,但是可以通过现象来判断它的属性。如果这么说起来你听的有点麻烦,那么我问你:"请问:什么是桌子?" 我想你可能说:上面是个平板下面有四根腿撑着的木头叫做桌子.那么接着反问你:板凳算不算是桌子?如果算,为什么不叫板凳是桌子?如果不算,桌子不也是四根腿,一面平板吗!所以究其本质我们可以说:用来吃饭的载体我们可以判断它就是桌子。
同样的道理我们可以引申到堆叠上下文,我们只知道一些属性会触发上下文,但是并不知道堆叠上下文是什么。
所以触发堆叠上下文的内容有以下:
- 根元素(HTML)
- z-index值不为”auto“的绝对定位/相对定位
- 一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex
- opacity 属性值小于 1 的元素(参考 the specification for opacity)
- transform 属性值不为 "no ne"的元素
- mix-blend-mode 属性值不为 "normal"的元素
- filter值不为“none”的元素
- perspective值不为“none”的元素
- isolation 属性被设置为 "isolate"的元素
- position: fixed
- 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值(参考 这篇文章)
- -webkit-overflow-scrolling 属性被设置 "touch"的元素
通过上图我们可以看出,图中没有z-index。但是依然形成了堆叠上下文的效果。之所以引发这种效果的原因是满足了堆叠上下文的第一个条件根元素<html>
其次,如果父元素HTML是一个家长,是其内部都具备堆叠上下文的结构。但是如果给一个子元素单独设置堆叠上下文,而另一个子元素没有设置堆叠上下文,则没有设置堆叠上下文效果的内容将会被掩盖。
上图解释了如果两个子元素同时设置了堆叠上下文那么两个子元素则具备兄弟同时竞争,后出现的优先级较高的效果.
最后我们需要考虑到一种最特殊的情况:如果给最高级元素设置z-index:-1则后代元素就会显示出来,这是因为此时的层叠上下文从总体来看是一个整体,所以后代元素会显示出来,而不是被子代或者孙子代掩盖住。